{"openapi":"3.1.0","info":{"title":"Releases API","description":"REST API for the Releases changelog registry — orgs, products, sources, releases, and search.\n\n**Links:** [releases.sh](https://releases.sh) · [Narrative docs](https://releases.sh/docs/api/rest) · [Errors](https://releases.sh/docs/api/errors) · [MCP server](https://releases.sh/docs/api/mcp)","version":"1.0.0"},"servers":[{"url":"https://api.releases.sh","description":"Production"}],"components":{"schemas":{"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable, specific machine code (e.g. `not_found`, `rate_limited`). Never reworded once shipped, but open-ended — branch defensively on codes you don't recognize."},"type":{"type":"string","enum":["validation","unauthorized","forbidden","insufficient_scope","not_found","conflict","too_large","rate_limited","upstream","unavailable","internal"],"description":"Coarse category from a fixed set; determines the HTTP status. Safe to switch on."},"message":{"type":"string","description":"Human-readable explanation. May change; do not parse."},"details":{"description":"Optional structured context carried by select codes (e.g. `database_not_initialized`)."}},"required":["code","type","message"]}},"required":["error"],"description":"Standardized error response — every non-2xx response uses this shape. Switch on `error.type` (fixed set → HTTP status) or match `error.code` (specific, stable). See https://releases.sh/docs/api/errors."}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"relk_… | relu_… | OAuth JWT","description":"Machine/operator tokens use the relk_ prefix; self-serve read-only user keys use relu_; Sign in with Releases supplies an OAuth access token. Required scope depends on the endpoint."}}},"tags":[{"name":"Orgs","description":"Organizations — top-level publisher of releases."},{"name":"Sources","description":"Changelog sources owned by an org."},{"name":"Products","description":"Optional grouping layer between orgs and sources."},{"name":"Releases","description":"Individual release entries."},{"name":"Search","description":"Lexical, semantic, and hybrid search."},{"name":"Lookups","description":"On-demand resolution helpers."},{"name":"Stats","description":"Public registry statistics."},{"name":"Related","description":"Vectorize-backed similarity rails for releases and sources."},{"name":"Taxonomy","description":"Categories and tags."},{"name":"Collections","description":"Curated, named org playlists independent of category."},{"name":"Overviews","description":"AI-generated org and product summaries."},{"name":"Webhooks","description":"Webhook subscription management."}],"paths":{"/stats":{"get":{"operationId":"getStats","tags":["Stats"],"summary":"Public registry rollup with per-source activity","description":"Returns a hybrid payload: the flat back-compat `orgs/sources/releases/products` counts (used by the web homepage banner) merged with the richer `StatsSummary` shape — `period`, `totals`, `sourceHealth`, `sourceActivity`, and the 20 most recent fetch-log entries. Counts use `*_active` / `*_visible` views, so soft-deleted and hidden rows are excluded.","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":30},"description":"Lookback window for `releasesInPeriod`, `sourceHealth.stale/upToDate`, and `sourceActivity.recentReleases`. Defaults to 30."}],"responses":{"200":{"description":"Registry rollup","content":{"application/json":{"schema":{"type":"object","properties":{"orgs":{"type":"integer","minimum":0,"maximum":9007199254740991},"sources":{"type":"integer","minimum":0,"maximum":9007199254740991},"releases":{"type":"integer","minimum":0,"maximum":9007199254740991},"products":{"type":"integer","minimum":0,"maximum":9007199254740991},"period":{"type":"object","properties":{"days":{"type":"integer","minimum":1,"maximum":9007199254740991},"cutoff":{"type":"string"}},"required":["days","cutoff"]},"totals":{"type":"object","properties":{"organizations":{"type":"integer","minimum":0,"maximum":9007199254740991},"sources":{"type":"integer","minimum":0,"maximum":9007199254740991},"releases":{"type":"integer","minimum":0,"maximum":9007199254740991},"releasesInPeriod":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["organizations","sources","releases","releasesInPeriod"]},"sourceHealth":{"type":"object","properties":{"upToDate":{"type":"integer","minimum":0,"maximum":9007199254740991},"stale":{"type":"integer","minimum":0,"maximum":9007199254740991},"neverFetched":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["upToDate","stale","neverFetched"]},"sourceActivity":{"type":"array","items":{"type":"object","properties":{"sourceName":{"type":"string"},"sourceSlug":{"type":"string"},"sourceType":{"type":"string"},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"totalReleases":{"type":"number"},"recentReleases":{"type":"number"}},"required":["sourceName","sourceSlug","sourceType","orgName","lastFetchedAt","totalReleases","recentReleases"]}},"recentActivity":{"type":"array","items":{"type":"object","properties":{"sourceName":{"type":"string"},"sourceSlug":{"type":"string"},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"releasesFound":{"type":"number"},"releasesInserted":{"type":"number"},"totalReleases":{"type":"number"},"status":{"type":"string"},"durationMs":{"anyOf":[{"type":"number"},{"type":"null"}]},"error":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["sourceName","sourceSlug","orgName","releasesFound","releasesInserted","totalReleases","status","durationMs","error","createdAt"]}}},"required":["orgs","sources","releases","products","period","totals","sourceHealth","sourceActivity","recentActivity"]}}}}}}},"/site-notice":{"get":{"operationId":"getSiteNotice","tags":["Site"],"summary":"Current site-wide notice","description":"Returns the single active site notice, or `{ notice: null }` when none is published. An admin Bearer additionally sees a stored-but-inactive (draft) notice.","responses":{"200":{"description":"The current notice or null","content":{"application/json":{"schema":{"type":"object","properties":{"notice":{"anyOf":[{"type":"object","properties":{"active":{"type":"boolean"},"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"href":{"type":"string","maxLength":500},"placement":{"type":"string","enum":["home","banner"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"dismissible":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["active","message","placement","color","dismissible","updatedAt"]},{"type":"null"}]}},"required":["notice"]}}}}}},"put":{"operationId":"putSiteNotice","tags":["Site"],"summary":"Publish or update the site-wide notice","description":"Admin only. Upserts the single site notice. Set `active: false` to hide it.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The stored notice","content":{"application/json":{"schema":{"type":"object","properties":{"notice":{"anyOf":[{"type":"object","properties":{"active":{"type":"boolean"},"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"href":{"type":"string","maxLength":500},"placement":{"type":"string","enum":["home","banner"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"dismissible":{"type":"boolean"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["active","message","placement","color","dismissible","updatedAt"]},{"type":"null"}]}},"required":["notice"]}}}},"400":{"description":"Invalid notice body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Caller lacks admin scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean"},"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"href":{"type":"string","maxLength":500},"placement":{"type":"string","enum":["home","banner"]},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"dismissible":{"type":"boolean"}},"required":["active","message","placement","color","dismissible"]}}}}}},"/orgs":{"get":{"operationId":"getOrgs","tags":["Orgs"],"summary":"List organizations","description":"Paginated list of orgs with 30-day release sparklines. Supports `?q=` substring search on name/slug. Orgs that have no indexed releases yet are hidden by default; pass `?includeEmpty=true` to opt in. The response always carries `meta.emptyOrgCount` so a UI toggle can show how many are hidden without a second round-trip.","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Case-insensitive substring match on name or slug."},{"name":"category","in":"query","required":false,"schema":{"type":"string"},"description":"Filter to a single canonical category slug (e.g. `ai`, `devops`). Invalid values are ignored (unfiltered). `meta.emptyOrgCount` is scoped to the same filter."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"includeEmpty","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include orgs that have zero indexed releases. Default `false` — empty orgs are stubs from in-flight discovery or broken parsers and surface as noise on the public catalog."},{"name":"featured","in":"query","required":false,"schema":{"type":"boolean"},"description":"Filter to editorially featured orgs only (home-page rail). Default unfiltered."},{"name":"trackingRequested","in":"query","required":false,"schema":{"type":"string","enum":["1"]},"description":"Admin-only. Pass `1` to restrict to orgs that have stamped `trackingRequestedAt` (the self-serve listing owner-demand signal, #1947), ordered most-recent-first. Items still conform to `OrgListItemSchema` (same envelope as the public list) but carry the additive `trackingRequestedAt` field and zeroed stats — these are self-serve stub orgs with no processed sources yet. Requires admin bearer auth — a non-admin caller gets a 403, the param is never silently ignored."}],"responses":{"200":{"description":"Paginated org list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"featured":{"type":"boolean"},"status":{"type":"string","enum":["stub","tracked"]},"sourceCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"recentReleaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"lastActivity":{"anyOf":[{"type":"string"},{"type":"null"}]},"topProducts":{"type":"array","items":{"type":"string"}},"aliasDomains":{"type":"array","items":{"type":"string"}},"sparkline":{"minItems":30,"maxItems":30,"type":"array","items":{"type":"integer","minimum":0,"maximum":9007199254740991}},"trackingRequestedAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","slug","name","domain","description","category","avatarUrl","featured","sourceCount","releaseCount","recentReleaseCount","lastActivity","topProducts","sparkline"]}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991},"returned":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"hasMore":{"type":"boolean"}},"required":["page","pageSize","returned","hasMore"]},"meta":{"type":"object","properties":{"emptyOrgCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["emptyOrgCount"]}},"required":["items","pagination"]}}}},"403":{"description":"Admin scope required for `?trackingRequested=1`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/orgs/{slug}":{"get":{"operationId":"getOrgsBySlug","tags":["Orgs"],"summary":"Get organization detail","description":"Resolves by slug, `org_…` ID, primary domain, or domain alias. Authenticated callers also receive the org playbook (private; CDN cache opt-out).","responses":{"200":{"description":"Organization detail","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"isHidden":{"type":"boolean"},"autoGenerateContent":{"type":"boolean"},"overviewCadenceDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"featured":{"type":"boolean"},"fetchPaused":{"type":"boolean"},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"status":{"type":"string","enum":["stub","tracked"]},"locations":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"feed":{"type":"string"},"github":{"type":"string"},"appstore":{"type":"string"},"file":{"type":"string"},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"canonical":{"type":"boolean"},"basis":{"type":"string","enum":["curator","declared","detected","generated"]},"productId":{"anyOf":[{"type":"string"},{"type":"null"}]},"sourceId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["canonical","basis","productId","sourceId"]}},"tags":{"type":"array","items":{"type":"string"}},"sourceCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"releasesLast30Days":{"type":"integer","minimum":0,"maximum":9007199254740991},"avgReleasesPerWeek":{"type":"number"},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"trackingSince":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"accounts":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string"},"handle":{"type":"string"}},"required":["platform","handle"]}},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"sourceCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"createdAt":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","slug","name","url","description","sourceCount","createdAt","releaseCount"]}},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestAddedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"isPrimary":{"type":"boolean"},"isHidden":{"type":"boolean"},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"fetchPriority":{"anyOf":[{"type":"string","enum":["normal","low","paused"]},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"changeDetectedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"consecutiveNoChange":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"consecutiveErrors":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"nextFetchAfter":{"anyOf":[{"type":"string"},{"type":"null"}]},"medianGapDays":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastRetieredAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"productName":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","type","releaseCount","latestVersion","latestDate"]}},"overview":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","enum":["org","product"]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"lastContributingReleaseAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"generatedAt":{"type":"string"},"updatedAt":{"type":"string"},"citations":{"type":"array","items":{"type":"object","properties":{"sourceUrl":{"type":"string"},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseId":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseWebUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"startIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"endIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"citedText":{"type":"string"}},"required":["sourceUrl"]}}},"required":["scope","content","releaseCount","lastContributingReleaseAt","generatedAt","updatedAt"]},{"type":"null"}]},"playbook":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","const":"playbook"},"content":{"type":"string"},"updatedAt":{"type":"string"}},"required":["scope","content","updatedAt"]},{"type":"null"}]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","sourceCount","releaseCount","releasesLast30Days","avgReleasesPerWeek","lastFetchedAt","lastPolledAt","trackingSince","accounts","products","sources"]}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/orgs/{slug}/manifest":{"get":{"operationId":"getOrgsBySlugManifest","tags":["Orgs"],"summary":"Export the org as a releases.json manifest","description":"Reconstructs an owner-declared `releases.json` v2 domain manifest from the org's live products + sources — the inverse of the well-known materializer. Each source becomes a release locator (github/appstore/feed/url, mirroring fetch routing), nested under its product or top-level; the primary source is marked `canonical`. Intended as an editable baseline an owner can host at `/.well-known/releases.json`; the output validates against the v2 schema and round-trips through the fill-if-empty well-known sweep for enrichment. Hidden/soft-deleted entities are excluded.","responses":{"200":{"description":"The reconstructed releases.json domain manifest","content":{"application/json":{"schema":{"type":"object","properties":{"$schema":{"type":"string","format":"uri"},"version":{"type":"number","const":2},"registries":{"type":"object","properties":{"releases.sh":{"type":"object","properties":{"org":{"type":"string","pattern":"^org_[A-Za-z0-9]+$"},"product":{"type":"string","pattern":"^prd_[A-Za-z0-9]+$"},"verification":{"type":"string","minLength":1,"maxLength":500}},"additionalProperties":{}}},"additionalProperties":{}},"releases":{"maxItems":32,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"feed":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"appstore":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"file":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"title":{"type":"string","minLength":1,"maxLength":200},"canonical":{"type":"boolean"},"github":{"type":"string","pattern":"^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$"}},"additionalProperties":false}},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":2000},"category":{"type":"string","minLength":1,"maxLength":120},"avatar":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"tags":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":60}},"social":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40},"additionalProperties":{"type":"string","minLength":1,"maxLength":200}},"products":{"maxItems":24,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"slug":{"type":"string","minLength":1,"maxLength":120},"kind":{"type":"string","minLength":1,"maxLength":120},"category":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":2000},"website":{"type":"string","format":"uri"},"docs":{"type":"string","format":"uri"},"support":{"type":"string","format":"uri"},"social":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":40},"additionalProperties":{"type":"string","minLength":1,"maxLength":200}},"tags":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":60}},"archived":{"type":"boolean"},"releases":{"maxItems":8,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"feed":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"appstore":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"file":{"type":"string","format":"uri","pattern":"^https:\\/\\/.*"},"title":{"type":"string","minLength":1,"maxLength":200},"canonical":{"type":"boolean"},"github":{"type":"string","pattern":"^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$"}},"additionalProperties":false}}},"required":["name"],"additionalProperties":false}}},"required":["version"],"additionalProperties":false}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/orgs/{slug}/collections":{"get":{"operationId":"getOrgsBySlugCollections","tags":["Orgs"],"summary":"Collections this org belongs to","description":"Returns the curated collections that include this organization — either because the org itself is a member, or because one of its products is a member (e.g. a `coding-agents` collection that pins Claude Code surfaces on the Anthropic org page). Deduplicated and ordered alphabetically by collection name. Each item includes `memberCount` (visible public orgs + products, matching `GET /v1/collections`). Use `GET /v1/collections/:slug` for the full collection detail.","responses":{"200":{"description":"Collection membership list","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"memberCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"isFeatured":{"type":"boolean"},"previewMembers":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}},"previewOrgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle","description"]}}},"required":["slug","name","description","memberCount","isFeatured"]}}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/orgs/{slug}/accounts":{"get":{"operationId":"getOrgsBySlugAccounts","tags":["Orgs"],"summary":"List org social/platform accounts","description":"Returns the org's registered accounts (GitHub, Twitter, LinkedIn, etc.) as a paginated list. Pass `?platform=<name>` to fetch a single account by platform — returns the account object or `null` when not set. When the org holds multiple accounts for the platform, single-mode returns the oldest-linked one deterministically; use the full list (omit `?platform`) to retrieve them all. The 200 schema is a union of the paginated list (default) or a single `OrgAccountItem`/`null` (single-mode) — the OSS CLI depends on the single-row return shape.","parameters":[{"name":"platform","in":"query","required":false,"schema":{"type":"string"},"description":"When provided, returns a single `OrgAccountItem` for the given platform (or `null`). When absent, returns the full paginated list."},{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Paginated org accounts (default), or a single `OrgAccountItem`/`null` when `?platform=` is supplied","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"platform":{"type":"string"},"handle":{"type":"string"}},"required":["platform","handle"]}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991},"returned":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"hasMore":{"type":"boolean"}},"required":["page","pageSize","returned","hasMore"]}},"required":["items","pagination"]},{"type":"object","properties":{"platform":{"type":"string"},"handle":{"type":"string"}},"required":["platform","handle"]},{"type":"null"}]}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/orgs/{slug}/tags":{"get":{"operationId":"getOrgsBySlugTags","tags":["Orgs"],"summary":"List org tags","description":"Returns the org's tag names as a paginated list, sorted alphabetically. Returns an empty list (not 404) when the org has no tags.","responses":{"200":{"description":"Paginated tag name list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"string"}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991},"returned":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"hasMore":{"type":"boolean"}},"required":["page","pageSize","returned","hasMore"]}},"required":["items","pagination"]}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/orgs/{slug}/releases":{"get":{"operationId":"getOrgsBySlugReleases","tags":["Orgs"],"summary":"Org release feed (cursor-paginated)","description":"Returns the org's combined release feed across all sources, newest-first. Cursor-paginated — pass `nextCursor` from the previous response as `?cursor=` on the next request. Accepts `?source_type=`, `?kind=`, `?include_coverage=true`, `?include_prereleases=true`, and `?q=` full-text search.","parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from a previous response's `pagination.nextCursor`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Max releases to return. Defaults to 20, capped at 100."},{"name":"source_type","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by source type (e.g. `github`, `feed`, `scrape`)."},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},"description":"Filter by resolved entity kind (source.kind ?? product.kind). One of: platform, sdk, mobile, desktop, docs, integration, tool."},{"name":"product","in":"query","required":false,"schema":{"type":"string"},"description":"Restrict the feed to one product (slug or `prod_…` id, scoped to this org). Unknown product → 404."},{"name":"include_coverage","in":"query","required":false,"schema":{"type":"boolean"},"description":"When true, include coverage-side rows (hidden by default)."},{"name":"include_prereleases","in":"query","required":false,"schema":{"type":"boolean"},"description":"When true, include pre-release entries."},{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Full-text search query applied to release title and content."},{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Keep only releases published at or after this bound. Accepts an ISO date/datetime or relative shorthand (`90d`, `4w`, `6m`, `2y`). Filters `published_at`; undated releases are dropped."},{"name":"until","in":"query","required":false,"schema":{"type":"string"},"description":"Keep only releases published at or before this bound. Same input formats as `since`."},{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Release feed","content":{"application/json":{"schema":{"type":"object","properties":{"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]},"source":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"appStore":{"type":"object","properties":{"platform":{"type":"string","enum":["ios","macos"]},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["platform","iconUrl"]},"video":{"type":"object","properties":{"provider":{"type":"string","enum":["youtube","vimeo","wistia"]}},"required":["provider"]}},"required":["slug","name","type"]},"product":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},{"type":"null"}]},"groupSlug":{"type":"string"},"groupName":{"type":"string"}},"required":["version","title","summary","publishedAt","url","source"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]}},"required":["releases","pagination"]}},"text/markdown":{"schema":{"type":"string"}}}},"400":{"description":"Invalid `kind` value or unparseable `since`/`until`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/products":{"get":{"operationId":"getProducts","tags":["Products"],"summary":"List products","description":"Returns the paginated `{items, pagination}` envelope. Filter by `?orgId=` to scope to one org. Filter by `?kind=` to narrow to a specific entity kind.","parameters":[{"name":"orgId","in":"query","required":false,"schema":{"type":"string"},"description":"Scope results to one organization by ID."},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},"description":"Filter by entity kind. Direct match on the row's own kind — no inheritance from a parent. One of: platform, sdk, mobile, desktop, docs, integration, tool."}],"responses":{"200":{"description":"Products list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"orgId":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"sourceCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","name","slug","orgId","url","description","category","createdAt","sourceCount"]}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991},"returned":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"hasMore":{"type":"boolean"}},"required":["page","pageSize","returned","hasMore"]}},"required":["items","pagination"]}}}},"400":{"description":"Invalid kind value","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/orgs/{slug}/products":{"get":{"operationId":"getOrgsBySlugProducts","tags":["Products"],"summary":"List an organization's products","description":"Org-scoped product list — the canonical nested form of `GET /products?orgId=`. `:slug` accepts an org slug or `org_…` id. Returns the paginated `{items, pagination}` envelope. Filter by `?kind=` to narrow to a specific entity kind (direct match on the product's own kind).","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Organization slug or `org_…` id."},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},"description":"Filter by entity kind. Direct match on the row's own kind — no inheritance from a parent. One of: platform, sdk, mobile, desktop, docs, integration, tool."}],"responses":{"200":{"description":"Products list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"orgId":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"sourceCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","name","slug","orgId","url","description","category","createdAt","sourceCount"]}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991},"returned":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"hasMore":{"type":"boolean"}},"required":["page","pageSize","returned","hasMore"]}},"required":["items","pagination"]}}}},"400":{"description":"Invalid kind value","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/products/{identifier}":{"get":{"operationId":"getProductsByIdentifier","tags":["Products"],"summary":"Get product detail","description":"Resolves by slug or `prod_…` ID on the bare path, or by org-scoped slug pair. Returns the product row plus its sources, tags, and domain aliases.","responses":{"200":{"description":"Product detail with sources, tags, and aliases","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"orgId":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"embeddedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"deletedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["id","slug","name","type","url"]}},"tags":{"type":"array","items":{"type":"string"}},"aliases":{"type":"array","items":{"type":"string"}},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["version","title","summary","publishedAt","url"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["id","name","slug","orgId","url","description","category","createdAt","embeddedAt","deletedAt","sources","tags","aliases"]}}}},"400":{"description":"Bare slug supplied on `/products/:identifier` (#698 — use the org-scoped path or `/v1/lookups/product-by-slug`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"identifier","required":true}]}},"/orgs/{orgSlug}/products/{productSlug}":{"get":{"operationId":"getOrgsByOrgSlugProductsByProductSlug","tags":["Products"],"summary":"Get product detail","description":"Resolves by slug or `prod_…` ID on the bare path, or by org-scoped slug pair. Returns the product row plus its sources, tags, and domain aliases.","responses":{"200":{"description":"Product detail with sources, tags, and aliases","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"orgId":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"embeddedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"deletedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["id","slug","name","type","url"]}},"tags":{"type":"array","items":{"type":"string"}},"aliases":{"type":"array","items":{"type":"string"}},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["version","title","summary","publishedAt","url"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["id","name","slug","orgId","url","description","category","createdAt","embeddedAt","deletedAt","sources","tags","aliases"]}}}},"400":{"description":"Bare slug supplied on `/products/:identifier` (#698 — use the org-scoped path or `/v1/lookups/product-by-slug`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgSlug","required":true},{"schema":{"type":"string"},"in":"path","name":"productSlug","required":true}]}},"/products/{identifier}/tags":{"get":{"operationId":"getProductsByIdentifierTags","tags":["Products"],"summary":"List product tags","description":"Returns the product's tag names sorted alphabetically. Empty array when the product has no tags. Only a typed `prod_…` ID resolves on this path; bare slugs return 400 (#698). Slug-only callers should first resolve via `GET /v1/lookups/product-by-slug?slug=…` and re-hit this endpoint with the returned `productId`.","responses":{"200":{"description":"Tag names","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}},"400":{"description":"Bare slug supplied on `/products/:identifier/tags`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"identifier","required":true}]}},"/orgs/{org}/resolve/{slug}":{"get":{"operationId":"getOrgsByOrgResolveBySlug","tags":["Orgs"],"summary":"Resolve an org-scoped slug to a product or source","description":"Product-first: returns `{ kind: \"product\", product }` when a product owns the slug, else `{ kind: \"source\", source }` for a source, else 404. One round trip for the bare `/[org]/[slug]` web route (#1190).","parameters":[{"name":"org","in":"path","required":true,"schema":{"type":"string"},"description":"Organization slug or `org_…` ID."},{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Org-scoped product or source slug to resolve (product-first)."}],"responses":{"200":{"description":"Discriminated product or source detail","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"product"},"product":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"orgId":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"},"embeddedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"deletedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["id","slug","name","type","url"]}},"tags":{"type":"array","items":{"type":"string"}},"aliases":{"type":"array","items":{"type":"string"}},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["version","title","summary","publishedAt","url"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["id","name","slug","orgId","url","description","category","createdAt","embeddedAt","deletedAt","sources","tags","aliases"]}},"required":["kind","product"]},{"type":"object","properties":{"kind":{"type":"string","const":"source"},"source":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"orgId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"isHidden":{"type":"boolean"},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"isPrimary":{"type":"boolean"},"metadata":{"type":"string"},"changelogUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"hasChangelogFile":{"type":"boolean"},"org":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"releasesLast30Days":{"type":"integer","minimum":0,"maximum":9007199254740991},"avgReleasesPerWeek":{"type":"number"},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"changeDetectedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"trackingSince":{"type":"string"},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["version","title","summary","publishedAt","url"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]},"summaries":{"type":"object","properties":{"rolling":{"anyOf":[{"type":"object","properties":{"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"windowDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"summary":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["summary","releaseCount","generatedAt"]},{"type":"null"}]},"monthly":{"type":"array","items":{"type":"object","properties":{"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"windowDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"summary":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["summary","releaseCount","generatedAt"]}}},"required":["rolling","monthly"]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["id","slug","name","type","url","orgId","productId","productSlug","isHidden","isPrimary","metadata","org","releaseCount","releasesLast30Days","avgReleasesPerWeek","latestVersion","latestDate","lastFetchedAt","lastPolledAt","trackingSince","releases","pagination","summaries"]}},"required":["kind","source"]}]}}}},"404":{"description":"Neither a product nor a source matched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/products/{slug}/collections":{"get":{"operationId":"getProductsBySlugCollections","tags":["Products"],"summary":"Collections this product belongs to","description":"Returns the curated collections that pin this product, ordered alphabetically by collection name. Mirrors `GET /v1/orgs/:slug/collections` so the web 'Featured in' sidebar renders identically at the org and product levels — a `coding-agents` collection that pins Claude Code surfaces on the Claude Code product page. Each item includes `memberCount` (visible public orgs + products).","responses":{"200":{"description":"Collection membership list","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"memberCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"isFeatured":{"type":"boolean"},"previewMembers":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}},"previewOrgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle","description"]}}},"required":["slug","name","description","memberCount","isFeatured"]}}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/orgs/{orgSlug}/products/{productSlug}/collections":{"get":{"operationId":"getOrgsByOrgSlugProductsByProductSlugCollections","tags":["Products"],"summary":"Collections this product belongs to","description":"Returns the curated collections that pin this product, ordered alphabetically by collection name. Mirrors `GET /v1/orgs/:slug/collections` so the web 'Featured in' sidebar renders identically at the org and product levels — a `coding-agents` collection that pins Claude Code surfaces on the Claude Code product page. Each item includes `memberCount` (visible public orgs + products).","responses":{"200":{"description":"Collection membership list","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"memberCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"isFeatured":{"type":"boolean"},"previewMembers":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}},"previewOrgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle","description"]}}},"required":["slug","name","description","memberCount","isFeatured"]}}}}},"404":{"description":"Product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgSlug","required":true},{"schema":{"type":"string"},"in":"path","name":"productSlug","required":true}]}},"/releases/latest":{"get":{"operationId":"getReleasesLatest","tags":["Releases"],"summary":"Latest releases (cross-source feed)","description":"Cacheable cross-source feed ordered by `(publishedAt DESC, fetchedAt DESC, id DESC)`. `?source=` and `?org=` are mutually exclusive scopes. `?exclude=` strips releases by source type — comma-separated values from `github,scrape,feed,agent`. By default, coverage-side rows (releases that roll up into a canonical release) are hidden; pass `?include_coverage=true` to include them. Prereleases (canaries / alphas / betas / RCs) are also hidden by default — pass `?include_prereleases=true` to surface them, matching the source-feed and MCP defaults. The unfiltered homepage shape is served through KV (`X-Cache: HIT|MISS`); filtered requests bypass cache (`X-Cache: BYPASS`).","parameters":[{"name":"count","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"description":"Number of releases to return. Clamped to `[1, 100]`."},{"name":"source","in":"query","required":false,"schema":{"type":"string"},"description":"Scope to a single source by typed ID (`src_…`) or slug. Mutually exclusive with `org`."},{"name":"org","in":"query","required":false,"schema":{"type":"string"},"description":"Scope to an org's sources by typed ID (`org_…`) or slug. Mutually exclusive with `source`."},{"name":"include_coverage","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include coverage-side rows that normally roll up into a canonical release."},{"name":"include_prereleases","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include prereleases (canaries / alphas / betas / RCs). Hidden by default to match the source-feed and MCP defaults."},{"name":"exclude","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated source types to exclude. Allowed: `github`, `scrape`, `feed`, `agent`."},{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Keep only releases published at or after this bound. Accepts an ISO date/datetime or relative shorthand (`90d`, `4w`, `6m`, `2y`). Filters `published_at`; undated releases are dropped. Windowed requests bypass the KV cache (`X-Cache: BYPASS`)."},{"name":"until","in":"query","required":false,"schema":{"type":"string"},"description":"Keep only releases published at or before this bound. Same input formats as `since`."},{"name":"minImportance","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":5},"description":"Only include releases with AI-scored `importance` >= this value (1–5). Releases with no score (`null`) are excluded when set. Filtered requests bypass the KV cache (`X-Cache: BYPASS`)."}],"responses":{"200":{"description":"Latest releases","content":{"application/json":{"schema":{"type":"object","properties":{"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"type":"string","enum":["feature","rollup"]},"title":{"type":"string"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"webUrl":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"source":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgAvatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgGithubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["slug","name","type","orgSlug"]},"product":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["slug","name"]},{"type":"null"}]},"groupSlug":{"type":"string"},"groupName":{"type":"string"},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["id","version","type","title","summary","titleGenerated","titleShort","publishedAt","url","media","source"]}}},"required":["releases"]}}}},"400":{"description":"Invalid `exclude` value, unparseable `since`/`until`, invalid `minImportance`, or `source` and `org` both supplied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Source or org not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/releases/{id}/coverage":{"get":{"operationId":"getReleasesByIdCoverage","tags":["Releases"],"summary":"Get release coverage cluster","description":"Returns the role the given release plays in a coverage cluster. `standalone` means it is not in any cluster; `coverage` means it rolls up into `canonical`; `canonical` means it is the canonical row and `covers` enumerates the rollup-side releases.","responses":{"200":{"description":"Coverage cluster (discriminated by `role`)","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"role":{"type":"string","const":"standalone"},"canonical":{"type":"null"},"covers":{"minItems":0,"maxItems":0,"type":"array","items":{"not":{}}}},"required":["role","canonical","covers"]},{"type":"object","properties":{"role":{"type":"string","const":"coverage"},"canonical":{"type":"object","properties":{"coverageId":{"type":"string"},"canonicalId":{"type":"string"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}]},"decidedBy":{"type":"string"},"decidedAt":{"type":"string"},"sibling":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"sourceName":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},{"type":"null"}]},"thumbnail":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"alt":{"type":"string"}},"required":["url"]},{"type":"null"}]}},"required":["id","version","title","sourceName","publishedAt","org"]},{"type":"null"}]}},"required":["coverageId","canonicalId","reason","decidedBy","decidedAt"]},"covers":{"minItems":0,"maxItems":0,"type":"array","items":{"not":{}}}},"required":["role","canonical","covers"]},{"type":"object","properties":{"role":{"type":"string","const":"canonical"},"canonical":{"type":"null"},"covers":{"type":"array","items":{"type":"object","properties":{"coverageId":{"type":"string"},"canonicalId":{"type":"string"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}]},"decidedBy":{"type":"string"},"decidedAt":{"type":"string"},"sibling":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"sourceName":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},{"type":"null"}]},"thumbnail":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"alt":{"type":"string"}},"required":["url"]},{"type":"null"}]}},"required":["id","version","title","sourceName","publishedAt","org"]},{"type":"null"}]}},"required":["coverageId","canonicalId","reason","decidedBy","decidedAt"]}}},"required":["role","canonical","covers"]}]}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}]}},"/sources":{"get":{"operationId":"getSources","tags":["Sources"],"summary":"List sources","description":"Returns a bare array by default; pass `?envelope=true` for the paginated `{items, pagination}` shape. Filter by `?orgId=`, `?orgSlug=`, `?slug=` (exact source slug — one row per org that has a source with this slug, for detecting an ambiguous bare slug across orgs; distinct from the `?q=` substring search), `?productSlug=`, `?type=`, `?has_feed=`, `?stale=`, `?category=`, `?kind=`, `?independent=true`, `?hasChangelog=false` (sources with no tracked CHANGELOG file), `?minRels30d=N` (sources with at least N visible releases in the last 30 days). Free-text search via `?q=`.","parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},"description":"Filter by entity kind. Direct match on the row's own kind — no inheritance from the parent product. One of: platform, sdk, mobile, desktop, docs, integration, tool."}],"responses":{"200":{"description":"Sources (bare array unless `?envelope=true`)","content":{"application/json":{"schema":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"productName":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"isPrimary":{"type":"boolean"},"isHidden":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchPriority":{"anyOf":[{"type":"string","enum":["normal","low","paused"]},{"type":"null"}]},"changeDetectedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"consecutiveNoChange":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"consecutiveErrors":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"nextFetchAfter":{"anyOf":[{"type":"string"},{"type":"null"}]},"medianGapDays":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastRetieredAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","slug","type","url","orgName","orgSlug","productName","productSlug","isPrimary","isHidden","metadata","releaseCount","latestVersion","latestDate","lastFetchedAt","lastPolledAt","fetchPriority","changeDetectedAt","consecutiveNoChange","consecutiveErrors","nextFetchAfter","medianGapDays","lastRetieredAt"]}},{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"productName":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"isPrimary":{"type":"boolean"},"isHidden":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchPriority":{"anyOf":[{"type":"string","enum":["normal","low","paused"]},{"type":"null"}]},"changeDetectedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"consecutiveNoChange":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"consecutiveErrors":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"nextFetchAfter":{"anyOf":[{"type":"string"},{"type":"null"}]},"medianGapDays":{"anyOf":[{"type":"number"},{"type":"null"}]},"lastRetieredAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","name","slug","type","url","orgName","orgSlug","productName","productSlug","isPrimary","isHidden","metadata","releaseCount","latestVersion","latestDate","lastFetchedAt","lastPolledAt","fetchPriority","changeDetectedAt","consecutiveNoChange","consecutiveErrors","nextFetchAfter","medianGapDays","lastRetieredAt"]}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"pageSize":{"type":"integer","minimum":1,"maximum":9007199254740991},"returned":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalPages":{"type":"integer","minimum":0,"maximum":9007199254740991},"hasMore":{"type":"boolean"}},"required":["page","pageSize","returned","hasMore"]}},"required":["items","pagination"]}]}}}},"400":{"description":"Invalid kind value","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/sources/{slug}/releases":{"get":{"operationId":"getSourcesBySlugReleases","tags":["Sources"],"summary":"Source release feed","description":"Cursor-paginated release feed scoped to one source. Supports inline FTS filter via `?q=`, prerelease toggle (`?include_prereleases=`), and coverage flag (`?include_coverage=`). Cursor shape matches `/v1/orgs/:slug/releases`.","responses":{"200":{"description":"Releases page"},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/sources/{slug}":{"get":{"operationId":"getSourcesBySlug","tags":["Sources"],"summary":"Get source detail","description":"Resolves by slug or `src_…` ID on the bare path, or by org-scoped slug pair. Cursor-paginated `releases` array (`?cursor=` opaque cursor from a prior response's `pagination.nextCursor`, `?limit=` capped at 100); `?include_coverage=true` exposes coverage rows; `?include_prereleases=true` includes pre-release entries.","responses":{"200":{"description":"Source detail with paginated releases","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"orgId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"isHidden":{"type":"boolean"},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"isPrimary":{"type":"boolean"},"metadata":{"type":"string"},"changelogUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"hasChangelogFile":{"type":"boolean"},"org":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"releasesLast30Days":{"type":"integer","minimum":0,"maximum":9007199254740991},"avgReleasesPerWeek":{"type":"number"},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"changeDetectedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"trackingSince":{"type":"string"},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["version","title","summary","publishedAt","url"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]},"summaries":{"type":"object","properties":{"rolling":{"anyOf":[{"type":"object","properties":{"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"windowDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"summary":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["summary","releaseCount","generatedAt"]},{"type":"null"}]},"monthly":{"type":"array","items":{"type":"object","properties":{"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"windowDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"summary":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["summary","releaseCount","generatedAt"]}}},"required":["rolling","monthly"]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["id","slug","name","type","url","orgId","productId","productSlug","isHidden","isPrimary","metadata","org","releaseCount","releasesLast30Days","avgReleasesPerWeek","latestVersion","latestDate","lastFetchedAt","lastPolledAt","trackingSince","releases","pagination","summaries"]}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/orgs/{orgSlug}/sources/{sourceSlug}":{"get":{"operationId":"getOrgsByOrgSlugSourcesBySourceSlug","tags":["Sources"],"summary":"Get source detail","description":"Resolves by slug or `src_…` ID on the bare path, or by org-scoped slug pair. Cursor-paginated `releases` array (`?cursor=` opaque cursor from a prior response's `pagination.nextCursor`, `?limit=` capped at 100); `?include_coverage=true` exposes coverage rows; `?include_prereleases=true` includes pre-release entries.","responses":{"200":{"description":"Source detail with paginated releases","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"url":{"type":"string"},"orgId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"isHidden":{"type":"boolean"},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"isPrimary":{"type":"boolean"},"metadata":{"type":"string"},"changelogUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"hasChangelogFile":{"type":"boolean"},"org":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"releasesLast30Days":{"type":"integer","minimum":0,"maximum":9007199254740991},"avgReleasesPerWeek":{"type":"number"},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastPolledAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"changeDetectedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"trackingSince":{"type":"string"},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]}},"required":["version","title","summary","publishedAt","url"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]},"summaries":{"type":"object","properties":{"rolling":{"anyOf":[{"type":"object","properties":{"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"windowDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"summary":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["summary","releaseCount","generatedAt"]},{"type":"null"}]},"monthly":{"type":"array","items":{"type":"object","properties":{"year":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"month":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"windowDays":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"summary":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["summary","releaseCount","generatedAt"]}}},"required":["rolling","monthly"]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"notice":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":280},"linkText":{"type":"string","minLength":1,"maxLength":60},"coordinate":{"type":"string","minLength":1,"maxLength":200},"href":{"type":"string","maxLength":500,"format":"uri"}},"required":["message"]},{"type":"null"}]}},"required":["id","slug","name","type","url","orgId","productId","productSlug","isHidden","isPrimary","metadata","org","releaseCount","releasesLast30Days","avgReleasesPerWeek","latestVersion","latestDate","lastFetchedAt","lastPolledAt","trackingSince","releases","pagination","summaries"]}},"text/markdown":{"schema":{"type":"string"}}}},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgSlug","required":true},{"schema":{"type":"string"},"in":"path","name":"sourceSlug","required":true}]}},"/orgs/{orgSlug}/sources/{sourceSlug}/releases":{"get":{"operationId":"getOrgsByOrgSlugSourcesBySourceSlugReleases","tags":["Sources"],"summary":"Source release feed","description":"Cursor-paginated release feed scoped to one source. Supports inline FTS filter via `?q=`, prerelease toggle (`?include_prereleases=`), and coverage flag (`?include_coverage=`). Cursor shape matches `/v1/orgs/:slug/releases`.","responses":{"200":{"description":"Releases page"},"404":{"description":"Source not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"orgSlug","required":true},{"schema":{"type":"string"},"in":"path","name":"sourceSlug","required":true}]}},"/releases/{id}":{"get":{"operationId":"getReleasesById","tags":["Releases"],"summary":"Get release by ID","description":"Returns a single release by its typed `rel_…` ID. Suppressed and coverage-side rows are excluded via the `releases_visible` view — they return 404. The `content` field has CDN-origin media URLs rewritten in-place; the `media` array is parsed from the raw D1 JSON. Accepts `Accept: text/markdown` to receive the release formatted as Markdown. Accepts the friendly `rel_…-<slug>` URL segment form — the trailing slug is ignored for lookup. The response includes `webUrl`, the canonical releases.sh detail-page URL (Zendesk-style: ID + current title slug).","responses":{"200":{"description":"Release detail","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"sourceId":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":{"type":"string","enum":["feature","rollup"]},"title":{"type":"string"},"content":{"type":"string"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"migrationNotes":{"anyOf":[{"type":"string"},{"type":"null"}]},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"webUrl":{"type":"string"},"contentHash":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"suppressed":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"suppressedReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"prerelease":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"fetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"sourceName":{"anyOf":[{"type":"string"},{"type":"null"}]},"sourceSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"sourceType":{"anyOf":[{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},{"type":"null"}]},"org":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"isHidden":{"type":"boolean"}},"required":["slug","name"]},{"type":"null"}]},"product":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["slug","name"]},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]},"appStore":{"anyOf":[{"type":"object","properties":{"platform":{"type":"string","enum":["ios","macos"]},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["platform","iconUrl"]},{"type":"null"}]},"video":{"anyOf":[{"type":"object","properties":{"provider":{"type":"string","enum":["youtube","vimeo","wistia"]}},"required":["provider"]},{"type":"null"}]},"sourceIsHidden":{"type":"boolean"}},"required":["id","sourceId","version","type","title","content","summary","titleGenerated","titleShort","url","contentHash","media","publishedAt","suppressed","suppressedReason","prerelease","fetchedAt","sourceName","sourceSlug","sourceType","org","composition"]}}}},"404":{"description":"Release not found (or suppressed / coverage-only)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}]}},"/search":{"get":{"operationId":"getSearch","tags":["Search"],"summary":"Unified search across orgs, catalog, collections, releases, and chunks","description":"Returns orgs, catalog entries (products + standalone sources folded together), curated collections, release hits, and — on hybrid/semantic modes — CHANGELOG.md chunk hits in a single response.\n\nEntity sections (orgs/catalog) match at word boundaries — including camelCase transitions (\"ai\" matches OpenAI but not Em·ai·l) — and never via a domain TLD (\"ai\" does not match coderabbit.ai). Hits order by match quality: exact name/slug, then name prefix, then name word, then slug/domain/URL, then org category.\n\n`mode` selects the release-retrieval strategy: `lexical` (FTS5), `semantic` (vector-only), or `hybrid` (RRF fusion of FTS5 + vector; default). The handler echoes back the mode actually used, including `degraded: true` when a hybrid request fell back to lexical because Vectorize is unavailable.\n\n`?domain=` narrows the entire result set to one org (matched against `organizations.domain` and `domain_aliases.domain`). Invalid hostnames return 400; unknown hostnames return an empty envelope with `domainStatus: \"not_found\"` (distinct from \"matched but no hits\").\n\n`?category=` and `?collection=` scope orgs, catalog, and release hits to an org set — a fixed category slug (unknown → 400) or a curated collection's members (unknown → empty envelope with `collectionStatus: \"not_found\"`). Both compose with every other filter.\n\nWhen the query parses as a GitHub coordinate (`org/repo` or `github:org/repo`) and no orgs/catalog matched, the handler runs an on-demand lookup and embeds the result on `lookup`. Coordinate-shaped queries are not suppressed by tangential release/chunk hits.\n\nCollections surface via two paths: a direct match on the collection's name/description (lexical in every mode, plus a vector match in hybrid/semantic mode — vector hits below the relevance floor are dropped so off-topic queries return no collections) and a member rollup that includes every collection containing one of the matched orgs. Each row carries a `via` discriminator (`\"direct\"` vs `\"member\"`); `matchedOrgSlugs` on member rows names the result-set orgs that triggered the rollup so a UI can render an \"includes X\" hint.\n\nContent negotiation: `Accept: text/markdown` returns a Markdown-rendered version of the same payload.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Search query. Required."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":20},"description":"Per-section result cap. Each of orgs/catalog/releases respects this independently."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0},"description":"Release-list offset (lexical mode only)."},{"name":"mode","in":"query","required":false,"schema":{"type":"string","enum":["lexical","semantic","hybrid"],"default":"hybrid"},"description":"Release-retrieval strategy."},{"name":"domain","in":"query","required":false,"schema":{"type":"string"},"description":"Narrow results to the org owning this domain."},{"name":"product","in":"query","required":false,"schema":{"type":"string"},"description":"Narrow release and catalog hits to a specific product's sources. Accepts a `prod_…` typed ID or an `orgSlug/productSlug` coordinate (e.g. `vercel/next-js`). Bare slugs (no `/` prefix) are rejected as ambiguous. Unknown products return an empty envelope with `productStatus: \"not_found\"`. Composes with `domain`, `kind`, `since`, and `until`."},{"name":"category","in":"query","required":false,"schema":{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},"description":"Narrow orgs, catalog, and release hits to organizations in this category (the slugs `GET /v1/categories` lists; curator aliases resolve to canonical). Unknown values are rejected with 400. The response echoes the resolved slug as `category` with `categoryStatus: \"matched\"`. Composes with every other filter."},{"name":"collection","in":"query","required":false,"schema":{"type":"string"},"description":"Narrow orgs, catalog, and release hits to the member organizations of this curated collection (by slug, e.g. `coding-agents`). Unknown slugs return an empty envelope with `collectionStatus: \"not_found\"` (mirrors `domain`). Composes with every other filter."},{"name":"include_coverage","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include coverage-side rows that normally roll up into a canonical release."},{"name":"include_content","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include full markdown `content` on each release hit. Default false — hits ship `summary` + `media` only (list/card surfaces). Use `GET /v1/releases/:id` for the full body when not opted in."},{"name":"include_empty","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include orgs with zero indexed releases in the `orgs` section. Default false — empty orgs are stubs and surface as noise. `?domain=` short-circuits this and always returns the resolved org."},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},"description":"Filter to a specific source/product kind. Release hits resolve through `source.kind ?? product.kind`; catalog hits filter on the row's own kind. The orgs and collections sections are unaffected; changelog chunk hits are unaffected."},{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"Keep only release hits published at or after this bound. Accepts an ISO date/datetime or relative shorthand (`90d`, `4w`, `6m`, `2y`). Filters `published_at`; releases with no date are dropped. The orgs/catalog/collections sections are unaffected."},{"name":"until","in":"query","required":false,"schema":{"type":"string"},"description":"Keep only release hits published at or before this bound. Same input formats as `since`. Filters `published_at`; releases with no date are dropped."}],"responses":{"200":{"description":"Unified search response. JSON by default; Markdown when `Accept: text/markdown` is sent.","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"domain":{"type":"string"},"domainStatus":{"type":"string","enum":["matched","not_found"]},"category":{"type":"string"},"categoryStatus":{"type":"string","enum":["matched"]},"collection":{"type":"string"},"collectionStatus":{"type":"string","enum":["matched","not_found"]},"orgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["stub","tracked"]},"aliasDomains":{"type":"array","items":{"type":"string"}}},"required":["slug","name","domain","avatarUrl","category"]}},"catalog":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgAvatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string"},{"type":"null"}]},"entryType":{"type":"string","enum":["product","source"]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]},"sourceSlug":{"type":"string"},"sourceType":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]}},"required":["slug","name","orgSlug","orgName","category","entryType"]}},"sources":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["github","scrape","feed","agent","appstore","video"]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["slug","name","type","orgSlug","orgName","productSlug"]}},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"sourceSlug":{"type":"string"},"sourceName":{"type":"string"},"sourceType":{"type":"string"},"appStore":{"anyOf":[{"type":"object","properties":{"platform":{"type":"string","enum":["ios","macos"]},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["platform","iconUrl"]},{"type":"null"}]},"video":{"anyOf":[{"type":"object","properties":{"provider":{"type":"string","enum":["youtube","vimeo","wistia"]}},"required":["provider"]},{"type":"null"}]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"content":{"type":"string"},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"score":{"type":"number"},"type":{"type":"string","enum":["feature","rollup"]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","sourceSlug","sourceName","orgSlug","version","title","summary","publishedAt"]}},"collections":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"memberCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"via":{"type":"string","enum":["direct","member"]},"score":{"type":"number"},"matchedOrgSlugs":{"type":"array","items":{"type":"string"}},"previewMembers":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}}},"required":["slug","name","description","memberCount","via"]}},"chunks":{"type":"array","items":{"type":"object","properties":{"sourceSlug":{"type":"string"},"sourceName":{"type":"string"},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"filePath":{"type":"string"},"offset":{"type":"integer","minimum":0,"maximum":9007199254740991},"length":{"type":"integer","minimum":0,"maximum":9007199254740991},"heading":{"anyOf":[{"type":"string"},{"type":"null"}]},"snippet":{"type":"string"},"score":{"type":"number"}},"required":["sourceSlug","sourceName","orgSlug","filePath","offset","length","heading","snippet","score"]}},"mode":{"type":"string","enum":["lexical","semantic","hybrid"]},"degraded":{"type":"boolean"},"degradedReason":{"type":"string"},"lookup":{"anyOf":[{"type":"object","properties":{"status":{"type":"string","enum":["indexed","existing","empty","not_found","deferred"]},"source":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["id","slug","name","url","discovery"]},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"thumbnail":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"alt":{"type":"string"}},"required":["url"]},{"type":"null"}]}},"required":["id","version","title","publishedAt"]}},"relatedOrg":{"anyOf":[{"type":"object","properties":{"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"required":["id","slug","name","url"]}}},"required":["org","sources"]},{"type":"null"}]}},"required":["status","relatedOrg"]},{"type":"null"}]}},"required":["query","orgs","catalog","sources","releases"]}},"text/markdown":{"schema":{"type":"string"}}}},"400":{"description":"Missing `q`, invalid `domain` hostname, unknown `kind` or `category` value, or unparseable `since`/`until`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/related/releases":{"get":{"operationId":"getRelatedReleases","tags":["Related"],"summary":"Releases semantically similar to an anchor release","description":"Pulls the anchor's vector from the `RELEASES_INDEX` Vectorize index via `getByIds`, then runs a follow-up `query` with that vector. The anchor itself is always excluded from results. `scope=org` filters by the anchor's org id (Vectorize metadata filter on `org_id`); `scope=global` (default) is unscoped.\n\n**Degrades gracefully:** when the binding is missing, the anchor isn't embedded yet, or Vectorize errors, the response is `{ degraded: true, degradedReason, items: [] }` with HTTP 200 — callers render nothing in that case. `degradedReason` is human-readable and not stable.\n\n**Ranking:** `topK` is over-fetched (`min(max(limit * 10, 50), 100)`), then candidates are ranked server-side by `cosine × recency × contentWeight` and sliced to `limit`. Content-free releases (empty bodies, boilerplate \"no changes\" notes) are dropped entirely; short-but-real releases are down-weighted; recency uses a 45-day half-life. Items are returned already in display order.","parameters":[{"name":"release","in":"query","required":true,"schema":{"type":"string"},"description":"Anchor release id (`rel_…`)."},{"name":"scope","in":"query","required":false,"schema":{"type":"string","enum":["org","global"],"default":"global"},"description":"Restrict candidates to the anchor's org, or run unscoped."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":25,"default":8},"description":"Max neighbors to return. Clamped to 1–25."},{"name":"excludeOrg","in":"query","required":false,"schema":{"type":"string"},"description":"Org slug to drop from results before slicing. Used by the global rail to avoid overlap with an org-scoped rail rendered alongside it."}],"responses":{"200":{"description":"Successful or degraded neighbor list.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","enum":["org","global"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"summary":{"type":"string"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"thumbnail":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"alt":{"type":"string"}},"required":["url"]},{"type":"null"}]},"score":{"type":"number"},"source":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"productName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgAvatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"appStore":{"type":"object","properties":{"platform":{"type":"string","enum":["ios","macos"]},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["platform","iconUrl"]}},"required":["id","slug","name","productName","orgSlug","orgName","orgAvatarUrl"]}},"required":["id","title","version","url","publishedAt","summary","titleGenerated","titleShort","thumbnail","score","source"]}}},"required":["scope","items"]},{"type":"object","properties":{"degraded":{"type":"boolean","const":true},"degradedReason":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"summary":{"type":"string"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"thumbnail":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"},"alt":{"type":"string"}},"required":["url"]},{"type":"null"}]},"score":{"type":"number"},"source":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"productName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgAvatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"appStore":{"type":"object","properties":{"platform":{"type":"string","enum":["ios","macos"]},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["platform","iconUrl"]}},"required":["id","slug","name","productName","orgSlug","orgName","orgAvatarUrl"]}},"required":["id","title","version","url","publishedAt","summary","titleGenerated","titleShort","thumbnail","score","source"]}}},"required":["degraded","degradedReason","items"]}]}}}},"400":{"description":"Missing `release` query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No release matches the supplied id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/related/sources":{"get":{"operationId":"getRelatedSources","tags":["Related"],"summary":"Sources semantically similar to an anchor source","description":"Pulls the anchor source's vector from the polymorphic `ENTITIES_INDEX` (orgs + products + sources) via `getByIds`, then runs `query` restricted to `type=source` so the candidate pool isn't wasted on parent orgs/products that would be filtered out post-hydration anyway. `scope=org` adds an `org_id` filter; `scope=global` (default) keeps the source filter only.\n\n**Degrades gracefully** the same way `/v1/related/releases` does — missing binding, unembedded anchor, or query error returns `{ degraded: true, degradedReason, items: [] }` with HTTP 200.\n\nEach surviving row carries its source basics plus an org rollup and a recent-release window-function stat block (`releaseCount`, `latestDate`, `latestTitle`, `latestVersion`, `recentCount`) so a rail card can render without follow-up requests.","parameters":[{"name":"source","in":"query","required":true,"schema":{"type":"string"},"description":"Anchor source id (`src_…`) or slug."},{"name":"scope","in":"query","required":false,"schema":{"type":"string","enum":["org","global"],"default":"global"},"description":"Restrict candidates to the anchor's org, or run unscoped."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":25,"default":6},"description":"Max neighbors to return. Clamped to 1–25."}],"responses":{"200":{"description":"Successful or degraded neighbor list.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","enum":["org","global"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"score":{"type":"number"},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgAvatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"recentCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","slug","name","type","url","score","orgSlug","orgName","orgAvatarUrl","releaseCount","latestDate","latestTitle","latestVersion","recentCount"]}}},"required":["scope","items"]},{"type":"object","properties":{"degraded":{"type":"boolean","const":true},"degradedReason":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"score":{"type":"number"},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgName":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgAvatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"latestDate":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestTitle":{"anyOf":[{"type":"string"},{"type":"null"}]},"latestVersion":{"anyOf":[{"type":"string"},{"type":"null"}]},"recentCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","slug","name","type","url","score","orgSlug","orgName","orgAvatarUrl","releaseCount","latestDate","latestTitle","latestVersion","recentCount"]}}},"required":["degraded","degradedReason","items"]}]}}}},"400":{"description":"Missing `source` query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No source matches the supplied identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/lookups":{"post":{"operationId":"postLookups","tags":["Lookups"],"summary":"On-demand GitHub source materialization","description":"Resolves a GitHub `org/repo` coordinate to a registry source. Idempotent — if the source already exists, returns it with `status: \"existing\"`; otherwise probes GitHub, inserts a hidden `on_demand` source row (and a new `on_demand` org when no curated org claims the segment), and ingests up to 100 releases.\n\nNegative results (`not_found`, `empty`) are cached in KV (24h and 6h respectively) so repeat probes don't re-hit GitHub. `deferred` outcomes (rate-limit, 5xx) are not cached and let the next cron pass retry.\n\nBody requires `provider: \"github\"` — other providers are explicitly rejected, not silently accepted. Coordinate must match `{org}/{repo}` (case-insensitive; URLs are deduped via `LOWER(sources.url)`).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Lookup result. Inspect `status` to disambiguate outcomes.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["indexed","existing","empty","not_found","deferred"]},"source":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"url":{"type":"string"},"orgId":{"anyOf":[{"type":"string"},{"type":"null"}]},"productId":{"anyOf":[{"type":"string"},{"type":"null"}]},"isHidden":{"anyOf":[{"type":"boolean"},{"type":"null"}]},"discovery":{"type":"string","enum":["curated","agent","on_demand"]},"metadata":{"anyOf":[{"type":"string"},{"type":"null"}]},"stars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"starsFetchedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string"}},"required":["id","slug","name","type","url","orgId","productId","metadata"],"additionalProperties":{}},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"sourceId":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["id","sourceId","version","title","url","publishedAt"],"additionalProperties":{}}},"relatedOrg":{"anyOf":[{"type":"object","properties":{"org":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"required":["id","slug","name","url"]}}},"required":["org","sources"]},{"type":"null"}]}},"required":["status","relatedOrg"]}}}},"400":{"description":"Missing JSON body, unsupported provider, or malformed coordinate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/lookups/source-by-slug":{"get":{"operationId":"getLookupsSourceBySlug","tags":["Lookups"],"summary":"Resolve a bare source slug to its canonical org-scoped home","description":"Translation aid for clients holding a bare source slug. Returns the org-scoped tuple `{ sourceId, sourceSlug, orgSlug }` so callers can rewrite to the canonical `/v1/orgs/:orgSlug/sources/:sourceSlug` path before the bare API path stops resolving slugs (#698 final piece).\n\nReturns the **oldest** match by `(createdAt, id)` so repeated calls land on the same row. Carries `Sunset: Sun, 01 Nov 2026 00:00:00 GMT` on success.","parameters":[{"name":"slug","in":"query","required":true,"schema":{"type":"string"},"description":"Bare source slug to resolve."}],"responses":{"200":{"description":"Canonical home for the slug","content":{"application/json":{"schema":{"type":"object","properties":{"sourceId":{"type":"string"},"sourceSlug":{"type":"string"},"orgSlug":{"type":"string"}},"required":["sourceId","sourceSlug","orgSlug"]}}},"headers":{"Sunset":{"description":"RFC 8594 sunset date for this resolution shape","schema":{"type":"string"}}}},"400":{"description":"Missing `slug` query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No source matches the slug","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/lookups/source-by-coordinate":{"get":{"operationId":"getLookupsSourceByCoordinate","tags":["Lookups"],"summary":"Resolve a GitHub owner/repo coordinate to an indexed source (read-only, no materialize)","description":"Read-only counterpart to `POST /v1/lookups`: given `coordinate=owner/repo` (optionally `github:owner/repo`), returns the canonical org-scoped tuple `{ sourceId, sourceSlug, orgSlug }` for a matching **visible** catalog source, or 404 when the repo isn't indexed. Unlike the POST, it never probes GitHub or materializes a hidden stub. Matches `sources.url` case-insensitively; on a multi-row case collision it prefers the exact-case row, then the oldest by `(createdAt, id)`.","parameters":[{"name":"coordinate","in":"query","required":true,"schema":{"type":"string"},"description":"GitHub coordinate, e.g. \"honojs/hono\" or \"github:honojs/hono\"."}],"responses":{"200":{"description":"Canonical home for the indexed repo","content":{"application/json":{"schema":{"type":"object","properties":{"sourceId":{"type":"string"},"sourceSlug":{"type":"string"},"orgSlug":{"type":"string"}},"required":["sourceId","sourceSlug","orgSlug"]}}}},"400":{"description":"Missing `coordinate`, or not a parseable github owner/repo coordinate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No visible source matches the coordinate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/lookups/product-by-slug":{"get":{"operationId":"getLookupsProductBySlug","tags":["Lookups"],"summary":"Resolve a bare product slug to its canonical org-scoped home","description":"Same semantics as `/v1/lookups/source-by-slug` but for products. Returns `{ productId, productSlug, orgSlug }` so callers can rewrite to `/v1/orgs/:orgSlug/products/:productSlug` before the bare path stops resolving slugs. Oldest match by `(createdAt, id)`. Carries `Sunset: Sun, 01 Nov 2026 00:00:00 GMT` on success.","parameters":[{"name":"slug","in":"query","required":true,"schema":{"type":"string"},"description":"Bare product slug to resolve."}],"responses":{"200":{"description":"Canonical home for the slug","content":{"application/json":{"schema":{"type":"object","properties":{"productId":{"type":"string"},"productSlug":{"type":"string"},"orgSlug":{"type":"string"}},"required":["productId","productSlug","orgSlug"]}}},"headers":{"Sunset":{"description":"RFC 8594 sunset date for this resolution shape","schema":{"type":"string"}}}},"400":{"description":"Missing `slug` query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No product matches the slug","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/lookups/by-domain":{"get":{"operationId":"getLookupsByDomain","tags":["Lookups"],"summary":"Resolve a domain to its owning org and any matching products","description":"Normalizes the input domain (lowercased, no scheme/path/www), exact-matches against `organizations.domain` (primary) and `domain_aliases.domain` (alias for either an org or a product), and returns whatever it finds.\n\nOn a complete miss, when `listing-self-serve-enabled` is on, the handler may probe `https://{domain}/.well-known/releases.json` in-request and materialize a stub org (basis: declared) via the same core as the listing activate path and the domain-demand cron. Probe budget is per-domain (a few attempts per ~10 min rolling window) plus a per-IP rate limit on the outbound branch; budget exhaustion returns 404 (not 429). Misses still record `domain_demand` for the nightly sweep backstop.\n\nProducts can be populated even when `org` is null — a product alias may point at a domain its parent org doesn't claim as primary.","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"},"description":"Hostname to resolve. Server normalizes (lowercases, strips scheme/path/www)."}],"responses":{"200":{"description":"Resolved org and/or product matches (including a just-materialized stub)","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"org":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"category":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"matchedVia":{"type":"string","enum":["primary","alias"]},"status":{"type":"string","enum":["stub","tracked"]},"locations":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"feed":{"type":"string"},"github":{"type":"string"},"appstore":{"type":"string"},"file":{"type":"string"},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"canonical":{"type":"boolean"},"basis":{"type":"string","enum":["curator","declared","detected","generated"]},"productId":{"anyOf":[{"type":"string"},{"type":"null"}]},"sourceId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["canonical","basis","productId","sourceId"]}}},"required":["id","slug","name","domain","description","category","avatarUrl","matchedVia"]},{"type":"null"}]},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"orgId":{"type":"string"},"orgSlug":{"type":"string"},"orgName":{"type":"string"},"category":{"anyOf":[{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},{"type":"null"}]},"kind":{"anyOf":[{"type":"string","enum":["platform","sdk","mobile","desktop","docs","integration","tool"]},{"type":"null"}]}},"required":["id","slug","name","orgId","orgSlug","orgName","category"]}}},"required":["domain","org","products"]}}}},"400":{"description":"Missing or invalid `domain` query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Domain doesn't match any registered org or product (and JIT found no valid manifest)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-IP rate limit on the outbound JIT probe branch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/orgs/{slug}/overview":{"get":{"operationId":"getOrgsBySlugOverview","tags":["Overviews"],"summary":"Get org overview","description":"Returns the AI-generated knowledge page for the org, including its source citations (each with a canonical internal `releaseWebUrl` when the source resolved to an on-registry release). Returns `null` when no overview has been generated yet. The org is resolved by slug or typed `org_…` ID.","responses":{"200":{"description":"Org overview page, or null when none exists","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","enum":["org","product"]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"lastContributingReleaseAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"generatedAt":{"type":"string"},"updatedAt":{"type":"string"},"citations":{"type":"array","items":{"type":"object","properties":{"sourceUrl":{"type":"string"},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseId":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseWebUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"startIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"endIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"citedText":{"type":"string"}},"required":["sourceUrl"]}}},"required":["scope","content","releaseCount","lastContributingReleaseAt","generatedAt","updatedAt"]},{"type":"null"}]}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/products/{slug}/overview":{"get":{"operationId":"getProductsBySlugOverview","tags":["Overviews"],"summary":"Get product overview","description":"Returns the AI-generated knowledge page for the product, or `null` when no overview has been generated yet. The product is resolved by typed `prod_…` ID or slug via `productMatchByIdOrSlug`.","responses":{"200":{"description":"Product overview page, or null when none exists","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","enum":["org","product"]},"orgSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"productSlug":{"anyOf":[{"type":"string"},{"type":"null"}]},"content":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"lastContributingReleaseAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"generatedAt":{"type":"string"},"updatedAt":{"type":"string"},"citations":{"type":"array","items":{"type":"object","properties":{"sourceUrl":{"type":"string"},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseId":{"anyOf":[{"type":"string"},{"type":"null"}]},"releaseWebUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"startIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"endIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"citedText":{"type":"string"}},"required":["sourceUrl"]}}},"required":["scope","content","releaseCount","lastContributingReleaseAt","generatedAt","updatedAt"]},{"type":"null"}]}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/webhooks/{id}/test":{"post":{"operationId":"postWebhooksByIdTest","tags":["Webhooks"],"summary":"Queue an administrative webhook test delivery","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"The queued synthetic event identifier.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"403":{"description":"Admin scope required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Webhook subscription not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"WEBHOOK_DELIVERY_QUEUE binding missing, or idempotency storage/response replay is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/feedback":{"post":{"operationId":"postFeedback","tags":["Feedback"],"summary":"Submit product feedback","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}}],"responses":{"202":{"description":"Accepted feedback identifier.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"Missing/invalid JSON body, or message shorter than the minimum length","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Feedback intake disabled (kill switch), or idempotency storage/response replay is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/recommendations":{"post":{"operationId":"postRecommendations","tags":["Recommendations"],"summary":"Submit a source recommendation","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}}],"responses":{"202":{"description":"Accepted recommendation identifier.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"Invalid type, URL, or contact email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Recommendation intake disabled (kill switch), or idempotency storage/response replay is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/categories":{"get":{"operationId":"getCategories","tags":["Taxonomy"],"summary":"List all categories with org and product counts","description":"Categories are a fixed taxonomy (`CATEGORIES` in `@buildinternet/releases-core/categories`), so the response always includes every slug — including ones with zero members. `orgCount` and `productCount` are computed against `organizations_public` (excludes `on_demand` and soft-deleted orgs). `name` / `description` / `aliases` come from the optional `categories` metadata overlay; clients render their own fallback display name when no override is set.","responses":{"200":{"description":"Full category list, one row per canonical slug","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"aliases":{"type":"array","items":{"type":"string"}},"orgCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"productCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"previewMembers":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}}},"required":["slug","name","description","aliases","orgCount","productCount"]}}}}}}}},"/categories/{slug}":{"get":{"operationId":"getCategoriesBySlug","tags":["Taxonomy"],"summary":"Get category detail with member orgs and products","description":"Returns orgs and products whose `category` matches the canonical slug. Aliases redirect: a non-canonical slug that matches an alias in the `categories` overlay returns a `301 Moved Permanently` to the canonical URL. Unknown slugs (neither canonical nor aliased) return `404`.","responses":{"200":{"description":"Category detail with org and product rollups","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","enum":["ai","cloud","commerce","crm","database","design","developer-tools","devops","finance","framework","infrastructure","observability","productivity","security"]},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"aliases":{"type":"array","items":{"type":"string"}},"orgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl"]}},"products":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgSlug":{"type":"string"},"orgName":{"type":"string"}},"required":["slug","name","description","orgSlug","orgName"]}}},"required":["slug","name","description","aliases","orgs","products"]}}}},"301":{"description":"Slug is an alias; redirects to the canonical category URL"},"404":{"description":"Slug is neither canonical nor a known alias","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/categories/{slug}/releases":{"get":{"operationId":"getCategoriesBySlugReleases","tags":["Taxonomy"],"summary":"Cross-org release feed scoped to a category","description":"Aggregated release feed for a category rollup. Mirrors `/v1/collections/:slug/releases` (cursor pagination, content negotiation). Effective category is denormalized on `releases.effective_category` (`COALESCE(product.category, org.category)` stamped at insert / recompute) so the feed can seek by category instead of full-scanning releases (#886).\n\nNon-canonical slugs that match a known alias resolve to the canonical category internally (no redirect — feeds aren't bookmarked). Content negotiation: `Accept: text/markdown` returns a Markdown-rendered version.","parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque pagination cursor from a previous response's `pagination.nextCursor`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Max releases per page. Clamped to `[1, 100]`."},{"name":"include_prereleases","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include alpha/beta/rc/preview/nightly releases. Default false."},{"name":"orgs","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated org slugs to narrow the feed to a subset of the category's orgs. Unknown slugs are silently dropped; passing an `orgs=` value that resolves to nothing returns `releases: []`. Omit to include all orgs in the category."},{"name":"source_type","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated source types (`github`, `feed`, `scrape`, `agent`) to narrow the feed by ingest channel. Unknown tokens are silently dropped. Omit to include all source types."},{"schema":{"type":"string"},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Category release feed (or Markdown when `Accept: text/markdown` is sent)","content":{"application/json":{"schema":{"type":"object","properties":{"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]},"source":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["slug","name","type"]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},"product":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},{"type":"null"}]},"groupSlug":{"type":"string"},"groupName":{"type":"string"}},"required":["version","title","summary","publishedAt","url","source","org"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]}},"required":["releases","pagination"]}}}},"404":{"description":"Slug is neither canonical nor a known alias","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/tags/{slug}":{"get":{"operationId":"getTagsBySlug","tags":["Taxonomy"],"summary":"Get tag detail with member orgs and products","description":"Returns orgs and products tagged with the given slug. Tags are freeform (get-or-create on write paths); unknown slugs return `404`. Both rollups include orgs from `organizations_public` only — `on_demand` and soft-deleted orgs are excluded.","responses":{"200":{"description":"Tag detail with org and product rollups","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"orgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl"]}},"products":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"orgSlug":{"type":"string"},"orgName":{"type":"string"}},"required":["slug","name","description","orgSlug","orgName"]}}},"required":["slug","name","orgs","products"]}}}},"404":{"description":"Tag not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"slug","required":true}]}},"/collections":{"get":{"operationId":"getCollections","tags":["Collections"],"summary":"List curated collections","description":"Returns every collection with a member count and a small `previewMembers` array (capped at 3) so the list page can render inline avatars without a second round trip. `previewMembers` is the mixed-kind preview (orgs and products); `previewOrgs` is the legacy org-only preview retained for back-compat. Member counts and previews are joined through `organizations_public` (for orgs) and `products_active` (for products), so soft-deleted / on_demand rows never inflate the totals. Pass `?featured=1` to return only homepage-featured collections.","parameters":[{"name":"featured","in":"query","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"When `1` (or `true`), return only homepage-featured collections."}],"responses":{"200":{"description":"Collections, ordered by name (optionally filtered to featured).","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"memberCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"isFeatured":{"type":"boolean"},"previewMembers":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}},"previewOrgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle","description"]}}},"required":["slug","name","description","memberCount","isFeatured"]}}}}}}}},"/collections/{slug}":{"get":{"operationId":"getCollectionsBySlug","tags":["Collections"],"summary":"Get a collection's detail page payload","description":"Returns the collection's name/description plus its ordered members. `members` is the canonical mixed-kind list (orgs + products); `orgs` is the legacy org-only subset retained for back-compat. Orgs join through `organizations_public` and products through `products_active`, so soft-deleted / on_demand rows never leak via a collection. GitHub handles are picked deterministically from `org_accounts` so multi-handle orgs don't fan out the row.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Collection slug."}],"responses":{"200":{"description":"Collection detail with ordered members.","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"isFeatured":{"type":"boolean"},"dailySummaryEnabled":{"type":"boolean"},"members":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"kind":{"type":"string","const":"org"}},"required":["slug","name","domain","avatarUrl","githubHandle","description","kind"]},{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle"]},"kind":{"type":"string","const":"product"}},"required":["slug","name","description","org","kind"]}]}},"orgs":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["slug","name","domain","avatarUrl","githubHandle","description"]}}},"required":["slug","name","description","isFeatured","dailySummaryEnabled","members","orgs"]}}}},"404":{"description":"No collection with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/collections/{slug}/releases":{"get":{"operationId":"getCollectionsBySlugReleases","tags":["Collections"],"summary":"Interleaved release feed across a collection's members","description":"Cursor-paginated cross-member feed for the collection. Cursor shape and ordering match `/v1/orgs/:slug/releases`, so the same web parser works on both surfaces. Org members are resolved through `organizations_public`, product members through `products_active`, so soft-deleted / on_demand rows never contribute releases. Empty membership returns `releases: []` rather than an error.\n\n`orgs` and `products` query params each accept a comma-separated list of slugs and narrow the feed to that subset of the collection's members. Unknown slugs are silently dropped; passing values that resolve to an empty member set returns `releases: []`. Omit both to include every member.\n\nSupports `Accept: text/markdown` for an LLM-friendly rendering.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Collection slug."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Page size. Clamped to 1–100."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque pagination cursor returned by a prior call."},{"name":"include_prereleases","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include rows flagged as prereleases. Defaults to false."},{"name":"orgs","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated org slugs to narrow the feed to a subset of the collection's org members."},{"name":"products","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated product slugs to narrow the feed to a subset of the collection's product members. Product slugs are per-org; ambiguity is resolved by the membership of this specific collection."},{"name":"source_type","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated source types (`github`, `feed`, `scrape`, `agent`) to narrow the feed by ingest channel — typically used by the web UI to split GitHub tag drops from marketing posts. Unknown tokens are silently dropped. Omit to include all source types."}],"responses":{"200":{"description":"Cursor-paginated release feed.","content":{"application/json":{"schema":{"type":"object","properties":{"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"type":"string"},"summary":{"type":"string"},"content":{"type":"string"},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"fetchedAt":{"type":"string"},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"media":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["image","video","gif"]},"url":{"type":"string"},"alt":{"type":"string"},"r2Key":{"type":"string"},"r2Url":{"type":"string"},"linkUrl":{"type":"string"}},"required":["type","url"]}},"type":{"type":"string","enum":["feature","rollup"]},"prerelease":{"type":"boolean"},"titleGenerated":{"anyOf":[{"type":"string"},{"type":"null"}]},"titleShort":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]},"coverageCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"contentChars":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"contentTokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"composition":{"anyOf":[{"type":"object","properties":{"bugs":{"type":"integer","minimum":0,"maximum":9007199254740991},"features":{"type":"integer","minimum":0,"maximum":9007199254740991},"enhancements":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["bugs","features","enhancements"]},{"type":"null"}]},"source":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"}},"required":["slug","name","type"]},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},"product":{"anyOf":[{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},{"type":"null"}]},"groupSlug":{"type":"string"},"groupName":{"type":"string"}},"required":["version","title","summary","publishedAt","url","source","org"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]}},"required":["releases","pagination"]}}}},"404":{"description":"No collection with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/collections/{slug}/daily-summaries":{"get":{"operationId":"getCollectionsBySlugDailySummaries","tags":["Collections"],"summary":"Daily AI summaries for a collection","description":"Returns AI-generated daily summaries for the collection within the given date window (ET calendar days, inclusive). Defaults to the last 30 days. Rows are ordered newest-first. Summaries are generated nightly by the collection-summaries cron and only exist for days where the collection had at least one visible release.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Collection slug."},{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Inclusive start date (YYYY-MM-DD, ET). Defaults to 30 days ago."},{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Inclusive end date (YYYY-MM-DD, ET). Defaults to today."}],"responses":{"200":{"description":"Daily summaries for the collection.","content":{"application/json":{"schema":{"type":"object","properties":{"summaries":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"title":{"type":"string"},"summary":{"type":"string"},"takeaways":{"type":"array","items":{"type":"string"}},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["date","title","summary","takeaways","releaseCount"]}}},"required":["summaries"]}}}},"400":{"description":"Malformed `from`/`to` date (must be YYYY-MM-DD).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No collection with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/collections/{slug}/digests":{"get":{"operationId":"getCollectionsBySlugDigests","tags":["Collections"],"summary":"Weekly AI digests for a collection","description":"Returns AI-generated weekly \"mini blog post\" digests for the collection, newest-first, cursor-paginated. Rows omit `body`/`releaseIds` — fetch a single week via `GET /v1/collections/:slug/digests/:weekStart` for the full row. Digests are generated on ET Mondays for the just-closed week by the collection-summaries cron and only exist for weeks that cleared the quality floor (>=3 substantive releases).","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Collection slug."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Page size. Clamped to 1–100."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque pagination cursor returned by a prior call."}],"responses":{"200":{"description":"Weekly digests for the collection.","content":{"application/json":{"schema":{"type":"object","properties":{"digests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"weekStart":{"type":"string"},"title":{"type":"string"},"intro":{"type":"string"},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"}},"required":["id","weekStart","title","intro","releaseCount","generatedAt"]}},"pagination":{"type":"object","properties":{"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["nextCursor","limit"]}},"required":["digests","pagination"]}}}},"404":{"description":"No collection with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/collections/{slug}/digests/{weekStart}":{"get":{"operationId":"getCollectionsBySlugDigestsByWeekStart","tags":["Collections"],"summary":"One collection's weekly digest, with resolved release links","description":"Full digest row (title, intro, markdown body, cited release ids) for one ET week, plus server-resolved minimal release info (title, org, canonical `/release/*` path) for every cited release — resolved server-side so the web page never N+1s. `:weekStart` must be the Monday (YYYY-MM-DD, ET) starting the week. Release ids that no longer resolve (deleted/suppressed since generation) are silently dropped from `releases`.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Collection slug."},{"name":"weekStart","in":"path","required":true,"schema":{"type":"string"},"description":"ET Monday starting the week, YYYY-MM-DD."}],"responses":{"200":{"description":"Full digest row with resolved release links.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"weekStart":{"type":"string"},"title":{"type":"string"},"intro":{"type":"string"},"body":{"type":"string"},"releaseIds":{"type":"array","items":{"type":"string"}},"releaseCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"generatedAt":{"type":"string"},"releases":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"path":{"type":"string"},"org":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},"importance":{"anyOf":[{"type":"integer","minimum":1,"maximum":5},{"type":"null"}]}},"required":["id","title","path","org"]}}},"required":["id","weekStart","title","intro","body","releaseIds","releaseCount","generatedAt","releases"]}}}},"400":{"description":"Malformed `weekStart` (must be YYYY-MM-DD).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No collection with that slug, or no digest for that week.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/tokens":{"post":{"operationId":"postTokens","tags":["Authentication"],"summary":"Create a scoped API token","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}}],"responses":{"201":{"description":"Created API token, including the one-time secret.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"Invalid JSON body, missing/invalid name, scopes, principalType, principalId, or expiresAt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Admin scope required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Idempotency storage or response replay is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api-keys":{"post":{"operationId":"postApiKeys","tags":["Authentication"],"summary":"Create a user API key","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}}],"responses":{"201":{"description":"Created user API key, including the one-time secret.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"Invalid JSON body, name, scope, or expiresInDays","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Active user API key limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Idempotency storage or response replay is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/me/webhooks":{"post":{"operationId":"postMeWebhooks","tags":["Webhooks"],"summary":"Create a personal webhook subscription","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}}],"responses":{"201":{"description":"Created webhook subscription, including its one-time signing key.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"400":{"description":"Invalid url/description/scope/releaseType, or an unsafe webhook target","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Organization, source, or product not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Maximum webhook subscriptions per account reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"WEBHOOK_HMAC_MASTER not configured, or idempotency storage/response replay is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/me/webhooks/{id}/rotate-secret":{"post":{"operationId":"postMeWebhooksByIdRotateSecret","tags":["Webhooks"],"summary":"Rotate a personal webhook signing key","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"The new secret version and one-time signing key.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Webhook subscription not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"WEBHOOK_HMAC_MASTER not configured, or idempotency storage/response replay is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/me/webhooks/{id}/test":{"post":{"operationId":"postMeWebhooksByIdTest","tags":["Webhooks"],"summary":"Queue a personal webhook test delivery","description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"description":"Optional idempotency key. Reuse the same key only for an identical request; successful responses are replayable for 24 hours.","schema":{"type":"string","minLength":16,"maxLength":255,"pattern":"^[\\x21-\\x7e]+$"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"The queued synthetic event identifier.","headers":{"Idempotency-Replayed":{"description":"`true` when this response is a replay of an earlier successful request.","schema":{"type":"string","enum":["true"]}}}},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Webhook subscription not found, or not owned by the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"The key is already processing, or was reused with a different request fingerprint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-subscription or per-user test-delivery rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"WEBHOOK_DELIVERY_QUEUE binding missing, or idempotency storage/response replay is temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/workspaces/{workspaceId}/profile":{"patch":{"operationId":"patchWorkspacesByWorkspaceIdProfile","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"websiteUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"changelogUrl":{"anyOf":[{"type":"string"},{"type":"null"}]},"githubHandle":{"anyOf":[{"type":"string"},{"type":"null"}]}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"workspaceId","required":true}],"responses":{"200":{}}}},"/whats-changed":{"get":{"operationId":"getWhatsChanged","tags":["Releases"],"summary":"Changelog entries between two versions of a package (upgrade intelligence)","description":"Given a `package` and a `from`/`to` version, returns the ordered release entries in the half-open range `(from, to]` — `from` exclusive (you have it), `to` inclusive — with summaries, breaking-change verdicts (#1696), and migration notes. One call instead of N changelog pages.\n\nReads already-ingested releases only (no live fetch). Resolution is read-only: an exact catalog source-slug match, then a non-materializing GitHub `owner/repo` coordinate match. An unresolvable package returns `status: \"unknown\"` with HTTP 200 — a valid answer, not an error; npm/PyPI names absent from the catalog resolve to `unknown` until the name→source map (#1345) lands. Wide ranges are truncated to a token budget (newest entries kept), flagged via `truncated`.","parameters":[{"name":"package","in":"query","required":true,"schema":{"type":"string"},"description":"Package identifier — a catalog source slug or a GitHub \"owner/repo\" coordinate."},{"name":"from","in":"query","required":true,"schema":{"type":"string"},"description":"Version you're upgrading FROM (exclusive)."},{"name":"to","in":"query","required":true,"schema":{"type":"string"},"description":"Version you're upgrading TO (inclusive)."},{"name":"ecosystem","in":"query","required":false,"schema":{"type":"string","enum":["npm","pypi","github"]},"description":"Optional resolution hint. `github` enables the coordinate match for a bare owner/repo."}],"responses":{"200":{"description":"Upgrade range (resolved or unknown — both are 200)","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["resolved","unknown"]},"package":{"type":"string"},"ecosystem":{"anyOf":[{"type":"string","enum":["npm","pypi","github"]},{"type":"null"}]},"from":{"type":"string"},"to":{"type":"string"},"source":{"anyOf":[{"type":"object","properties":{"sourceId":{"type":"string"},"sourceSlug":{"type":"string"},"orgSlug":{"type":"string"}},"required":["sourceId","sourceSlug","orgSlug"]},{"type":"null"}]},"entries":{"type":"array","items":{"type":"object","properties":{"version":{"anyOf":[{"type":"string"},{"type":"null"}]},"publishedAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"summary":{"anyOf":[{"type":"string"},{"type":"null"}]},"breaking":{"type":"string","enum":["unknown","none","minor","major"]},"migrationNotes":{"anyOf":[{"type":"string"},{"type":"null"}]},"url":{"anyOf":[{"type":"string"},{"type":"null"}]},"webUrl":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["version","publishedAt","title","summary","breaking","migrationNotes","url","webUrl"]}},"count":{"type":"number"},"truncated":{"type":"boolean"},"truncatedAtTokens":{"type":"number"}},"required":["status","package","ecosystem","from","to","source","entries","count","truncated"]}}}},"400":{"description":"Missing/invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listing/capabilities":{"get":{"operationId":"getListingCapabilities","tags":["Listing"],"summary":"Listing-lane capability flags","description":"Returns whether the self-serve listing lane and self-serve promotion are currently enabled. Public and anonymous; always reachable even when either kill switch is off (so clients can hide CTAs rather than offer a button that 404s).","responses":{"200":{"description":"ListingCapabilities","content":{"application/json":{"schema":{"type":"object","properties":{"selfServeEnabled":{"type":"boolean"},"promotionEnabled":{"type":"boolean"}},"required":["selfServeEnabled","promotionEnabled"],"additionalProperties":false}}}}}}},"/listing/validate":{"post":{"operationId":"postListingValidate","tags":["Listing"],"summary":"Validate a domain's releases.json and preview its listing","description":"Fetches https://{domain}/.well-known/releases.json live (HTTPS-only, 64KB, 5s), validates it against the v2 manifest schema, and returns a preview: identity, products, and per-locator classification, plus whether the domain is already listed. Public and anonymous; rate limited.","responses":{"200":{"description":"ListingValidationResult"},"404":{"description":"Lane disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","minLength":1,"maxLength":255}},"required":["domain"],"additionalProperties":false}}}}}},"/listing/activate":{"post":{"operationId":"postListingActivate","tags":["Listing"],"summary":"Activate an instant stub listing for an unlisted domain","description":"Re-validates https://{domain}/.well-known/releases.json server-side, then creates a stub org (basis: declared) for an unlisted domain. Already-stub domains take no write except an optional tracking-request stamp; tracked domains 409 with the org pointer. Public and anonymous; rate limited per IP and per domain.","responses":{"200":{"description":"Existing stub; tracking stamp updated (ListingActivateResult)"},"201":{"description":"Stub created (ListingActivateResult)"},"400":{"description":"Manifest invalid or unfetchable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Lane disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Domain already listed (tracked)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","minLength":1,"maxLength":255},"requestTracking":{"type":"boolean"}},"required":["domain"],"additionalProperties":false}}}}}},"/listing/claim":{"post":{"operationId":"postListingClaim","tags":["Listing"],"summary":"Start (or fetch) an ownership claim on a listed domain","description":"Signed-in only. Mints a pending claim with a well-known-token + DNS-TXT proof pair for a stub or tracked domain; idempotent once verified. 404s an unlisted domain.","responses":{"200":{"description":"Existing verified claim returned as-is (OrgClaim)"},"201":{"description":"Pending claim minted (OrgClaim)"},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Lane disabled, or the domain is not listed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","minLength":1,"maxLength":255}},"required":["domain"],"additionalProperties":false}}}}}},"/listing/claim/verify":{"post":{"operationId":"postListingClaimVerify","tags":["Listing"],"summary":"Check the proof for a pending ownership claim","description":"Signed-in only, and the claim must belong to the caller (404 otherwise — no existence oracle). Checks the well-known token file and the DNS TXT record; either passes. Fails closed on any ambiguous response. 200 whether or not it verifies.","responses":{"200":{"description":"ClaimVerifyResult (verified may be true or false)"},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such claim for this caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Claim expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"claimId":{"type":"string","minLength":1}},"required":["claimId"],"additionalProperties":false}}}}}},"/listing/claims":{"get":{"operationId":"getListingClaims","tags":["Listing"],"summary":"List the caller's own ownership claims","description":"Signed-in only. Lazily flips overdue pending claims to expired on read. Pending claims include the token + proof instructions; verified/expired do not.","responses":{"200":{"description":"ListingClaimsResult"},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Lane disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/listing/promote":{"post":{"operationId":"postListingPromote","tags":["Listing"],"summary":"Self-serve promotion of a claimed stub org to tracked","description":"Signed-in only, and the caller must hold a verified claim on the resolved org (403 otherwise). Materializes stored release locators into sources — tier-1 (feed/github/appstore) go live, tier-2 (bare url/file) land paused for curator review — and flips the org to tracked. Idempotent: an already-tracked org is a no-op success. Gated behind a dedicated kill switch (creates live fetching sources).","responses":{"200":{"description":"ListingPromoteResult"},"401":{"description":"Sign-in required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"No verified claim on this domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Lane or promotion flag disabled, or the domain is not listed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Promotion already in progress for this org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","minLength":1,"maxLength":255}},"required":["domain"],"additionalProperties":false}}}}}}}}