API Documentation

Everything you need to integrate RepoVital into your workflow.

Authentication

All requests to /score require an API key passed in the X-API-Key header.

Request header
X-API-Key: rv_your_api_key_here
Get a free API key (10 scores/day, no credit card) at repovital.com/#pricing. Free keys are emailed instantly.

The /badge and /health endpoints do not require authentication.

Endpoints

Base URL: https://api.repovital.com

GET /score Score a GitHub repository — requires X-API-Key

Parameters

ParamTypeRequiredDescription
repostringYesFull GitHub URL, e.g. https://github.com/django/django

Example request

curl
curl -H "X-API-Key: rv_your_api_key_here" \ "https://api.repovital.com/score?repo=https://github.com/django/django"

Example response

200 OK — JSON
{ "repo": "django/django", "score": 87, "tier": "Healthy", "scorer_version": "ml-v1", "scored_at": "2026-04-15T12:00:00Z", "archived": false, "fork": false, "message": null, "top_signals": [ { "name": "days_since_last_commit", "value": 1, "direction": "positive", "label": "Committed 1 day ago" }, { "name": "contributor_gini", "value": 0.41, "direction": "positive", "label": "Contributor distribution is healthy" }, { "name": "pr_merge_rate", "value": 0.94, "direction": "positive", "label": "94% of PRs merged" } ], "features": { "days_since_last_commit": 1, "contributor_gini": 0.41, "pr_merge_rate": 0.94, "release_cadence_cv": 0.32, "repo_age_days": 5420, "open_issue_age_p75": 14.2, "commit_velocity_slope": 0.003, "issue_response_p50": 4.1, "has_governance_docs": true } }

Response fields

FieldTypeDescription
repostringCanonical owner/name identifier
scoreint or null0–100 health score; null for Unscored repos
tierstringHealthy / Watch / At Risk / Critical / Archived / Unscored
scorer_versionstringWhich scoring path ran — see scorer_version table below
scored_atISO 8601 datetimeWhen the score was computed (cached for 24 hours)
archivedboolTrue if the repo is archived on GitHub
forkboolTrue if the repo is a fork; forks score low due to low independent activity
messagestring or nullHuman-readable explanation for special tiers (Archived, Unscored)
top_signalsarrayTop SHAP-ranked signals driving the score, each with name, value, direction, label
featuresobjectAll 9 raw feature values used by the model
GET /badge SVG health badge — no auth required

Returns an SVG badge showing the repo's health tier. Designed to be embedded in README files.

Parameters

ParamTypeRequiredDescription
repostringYesFull GitHub URL of the repository

README markdown snippet

This is the primary way to embed a RepoVital badge. Copy the snippet below, replace OWNER/REPO, and paste into your README.
![RepoVital](https://api.repovital.com/badge?repo=https://github.com/OWNER/REPO)

Live badge preview

This is a live badge for django/django:

Example request

GET https://api.repovital.com/badge?repo=https://github.com/django/django
GET /account View account details — requires X-API-Key or ?key=

View your current tier, daily usage, and manage your subscription. Returns an HTML page, not JSON.

Authentication

MethodExample
HeaderX-API-Key: rv_your_key_here
Query param?key=rv_your_key_here

Example request

GET https://api.repovital.com/account?key=rv_your_key_here

Page contents

FieldDescription
TierYour current plan (Free, Pro, Team, Business, or Enterprise)
Daily usageRequests used today vs. your daily limit
API keyPartially masked key, e.g. rv_1pEO…fJg
SubscriptionLink to the Stripe Customer Portal to manage or cancel

Score Tiers

Every scored repository falls into one tier. The ML model outputs a probability (0–1) which is multiplied by 100 to produce the score. A rules-based fallback applies the same thresholds to a weighted feature sum.

ML & Rules-based tiers

TierScore rangeMeaning
Healthy 72–100 Actively maintained
Watch 50–71 Some maintenance signals weakening
At Risk 28–49 Multiple signals declining
Critical 0–27 High abandonment risk

Special tiers

TierScoreCondition
Archived 0 Repo is archived on GitHub
Unscored null Repo <6 months old or has zero commits

The 9 Signals

RepoVital measures nine features for each repository.

Signal What it measures Why it matters
commit_velocity_slope Slope of weekly commit count over the trailing 12 months (positive = accelerating, negative = decelerating) A negative slope predicts future inactivity even when the repo looks active today
contributor_gini Gini coefficient of commit counts across all contributors (0 = equal, 1 = one person did everything) High concentration in one contributor is fragile — bus factor risk
days_since_last_commit Calendar days since the most recent commit The single strongest abandonment signal — a repo with no recent commits is likely unmaintained
has_governance_docs Whether the repo has CONTRIBUTING, CODE_OF_CONDUCT, or SECURITY files Governance docs correlate weakly with health; flag is low signal on its own
issue_response_p50 Median hours until the first maintainer comment on a new issue Fast response time indicates engaged maintainers; currently sparse in training data
open_issue_age_p75 75th percentile age (in days) of currently open issues A large backlog of old open issues signals the maintainer has lost bandwidth
pr_merge_rate Fraction of recently closed pull requests that were merged (vs. closed without merging) High merge rate indicates an active, accepting maintainer — low rate suggests a stalled queue
release_cadence_cv Coefficient of variation of time intervals between releases (tags + GitHub Releases combined) Low CV = regular, predictable releases; high CV = erratic or stopped shipping
repo_age_days Days since the repository was created Older repos have more track record to judge; very new repos are excluded from scoring

Rate Limits

Limits are enforced per API key per calendar day (UTC). Every /score response includes rate limit headers.

TierScores/dayPrice
Free10$0 — no credit card required
Pro100$9/month
Team1,000$29/month
Business10,000$79/month
EnterpriseUnlimitedContact [email protected]

Response headers

X-RateLimit-Limit Your daily limit (e.g. 10 for free tier)
X-RateLimit-Remaining Requests remaining today
X-RateLimit-Reset UTC timestamp when your daily counter resets
X-RateLimit-Warning Included when you have used ≥80% of your daily limit

429 Too Many Requests

When you exceed your daily limit, you receive a 429 with an upgrade_url field pointing to repovital.com/#pricing.

{ "detail": "Daily limit reached.", "upgrade_url": "https://repovital.com/#pricing" }

scorer_version field

Every score response includes a scorer_version string that tells you exactly which scoring path ran.

ValueTierMeaning
ml-v1 Healthy / Watch / At Risk / Critical ML model scored successfully
rules-v1 Healthy / Watch / At Risk / Critical ML failed; rules-based fallback applied
rules-v1-archived Archived Repo is archived on GitHub; pre-filter applied before feature extraction
rules-v1-new-repo Unscored Repo is less than 6 months old; insufficient signal to score reliably
rules-v1-insufficient-data Unscored Repo has zero commits; no feature data available

Edge Cases

Some repositories produce non-standard responses. Here is what to expect for each case.

Archived repositories

GitHub marks a repo archived when the owner freezes it. RepoVital hard-filters these before feature extraction.

{ "repo": "owner/repo", "score": 0, "tier": "Archived", "archived": true, "scorer_version": "rules-v1-archived", "message": "This repository is archived. Archived repos receive a Archived status regardless of historical activity." }

Unscored (new or empty repos)

Repos under 6 months old or with zero commits lack enough signal for the ML model to produce a reliable result. score is null.

{ "repo": "owner/new-repo", "score": null, "tier": "Unscored", "scorer_version": "rules-v1-new-repo", "message": "Repository is less than 6 months old - not enough signal to score reliably." }

Private or not-found repositories

If GitHub returns 403 or 404 for the requested repo, you get a clean HTTP 404 (never a 500).

HTTP 404 { "detail": "Repository not found or is private." }

Fork repositories

Forks score low because they have little independent activity relative to their upstream. The score is not overridden — the low number is the correct answer. The fork: true flag in the response helps callers add context in their UI.

{ "repo": "owner/forked-repo", "score": 18, "tier": "Critical", "fork": true, ... }