Public JSON API
Free · read-only · CORS open · static (no rate limits)
Every page on os-alt is generated from a small, hand-curated dataset of 100 paid SaaS and the 227 unique open-source projects we recommend as self-host replacements. This API exposes that dataset as JSON, regenerated on every deploy with fresh GitHub stats (stars, last commit, archived flag, alive/stale/dead classification).
No auth, no API keys, no rate limits — the responses are static files served from Vercel's CDN. Embed in dashboards, READMEs, blog posts, or your own tooling. If you build something on top, let us know.
Endpoints
GET /api/saas/index.json
List of every SaaS we cover, with slug, name, category, page URL, and the URL of the detail JSON for each.
curl -s https://code-rho-dun.vercel.app/api/saas/index.json | jq '.saas[0:3]' Schema
generated_at— ISO 8601 timestamp of the build that produced this filecount— number of SaaS entries (integer)slugs— array of slug strings, alphabetized by SaaS namesaas— array of objects:{slug, name, category, alternatives_count, page_url, api_url}
GET /api/saas/<slug>.json
Full detail for one SaaS: the editorial blurb, pricing anchor, every recommended open-source alternative, and live GitHub health for each alternative as of the last build.
curl -s https://code-rho-dun.vercel.app/api/saas/1password.json | jq '.alternatives[0]' Schema
generated_at— ISO 8601 timestampslug,name,category,blurb,saas_pricing_anchor— stringspage_url— string, path on the os-alt sitemigration_guide_url— string or null; present when a long-form migration guide exists-
alternatives— array of objects:name,github("owner/repo"),github_owner,github_name— stringslicense— SPDX-style string;license_note— string or nullsetup_time— string;setup_score—"easy" | "moderate" | "hard"monthly_cost,migration_sketch,good_fit_for,weak_at— strings-
health— object:status—"alive" | "stale" | "dead" | "unknown"stars— integer or nulllast_commit_at— ISO 8601 string or nulllast_commit_age_days— integer or null (computed at build time)open_issues— integer or nullarchived— boolean (archived repos are classified asdead)fetched_at— ISO 8601 string
GET /api/health.json
Flat list of every unique open-source repository we track, with its current health classification, star count, last commit date, and which os-alt SaaS pages list it. Useful for dashboards, OSS-health rollups, and READMEs that want to flag stale recommendations.
curl -s https://code-rho-dun.vercel.app/api/health.json | jq '.counts, .repos[] | select(.health == "dead") | .github' Schema
generated_at— ISO 8601 timestampcount— number of unique repositories trackedcounts— object:{alive, stale, dead, unknown}integer countshealth_thresholds— the day cutoffs used to classify each repo (currently 90d/365d)-
repos— array of objects:github("owner/repo"),owner,name— stringsstars,open_issues,last_commit_age_days— integers or nulllast_commit_at— ISO 8601 string or nullarchived— booleanhealth—"alive" | "stale" | "dead" | "unknown"listed_under— array of SaaS slugs that recommend this repo (e.g.["aws-s3", "google-cloud-storage"])fetched_at— ISO 8601 string
Notes
- All endpoints respond with
Content-Type: application/json; charset=utf-8andAccess-Control-Allow-Origin: *, so browserfetch()works from any origin. - Files are regenerated on every deploy. The directory rebuilds automatically on a daily GitHub Actions cron, so
generated_atis never more than ~24 hours old. - Health classification uses last-commit age:
alive≤ 90 days,stale≤ 365 days,dead> 365 days. Archived repos are alwaysdeadregardless of commit age. - The dataset is the same one rendering the human pages — there is no separate API store or queue. If a SaaS appears in the directory, it appears in the API at the same time.
- Read-only. There is no write API, no authentication, and no quotas.