API Reference
REST401) except /api/health (probes), /api/webhooks/github (HMAC signature) and /api/cron/* (CRON_SECRET bearer token). Parameters are query-string unless marked (body).Organization-mode responses
| Status | code | Meaning |
|---|---|---|
| 403 | no_groups | Signed in, but in no group yet (the page equivalent is /pending). |
| 403 | forbidden | The route's feature is not granted to any of your groups; flag names it. |
| 403 | unregistered | The API route is not in the access registry, so it is denied by default. |
| 403 | org_not_allowed | The account is not an active member of GITDASH_ALLOWED_ORGS; the session is cleared. |
| 503 | authz_unavailable | GitHub or the database could not be reached to check access. Retry shortly. |
/api/github/reposPersonal repositories the signed-in token can see. Organization repositories come from /api/github/org-repos.
/api/github/repo-overviewPer-workflow summaries for a repository — status, health, run history, trend, duration points.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/repo-doraRepository-level DORA 4 Keys computed from merged PRs and releases. Includes cycle breakdown, PR scatter, and throughput by week.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/repo-contributorsPer-contributor delivery stats for a repository: PRs merged, reviews given, avg lead time, avg PR size, review turnaround, first-pass approval rate, self-merges. Also returns reviewer load matrix and bus factor. Without days: the last 60 closed pull requests (repo Team tab). With days=30|90: every pull request merged in the window, read through GraphQL search and shared by everyone who can see the repository, plus window_days, median_hours_to_merge (the true median), prs_merged_total, prs_opened_in_window, prs_human_reviewed, prs_no_human_review, prs_self_merged, bot_reviews, review_pairs (pull requests, not review events), coverage, and is_bot / linked_logins / median_hours_to_merge / reviewed_prs on each row. A human review is a submitted APPROVED, CHANGES_REQUESTED or COMMENTED review by someone who is neither a bot nor the author. Account links are applied in both modes.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
days | number | Optional | 30 or 90: the Team insights window (see description). |
/api/github/contributor-profileFull contributor profile: KPI cards, 52-week activity calendar, weekly commits, PR funnel, commit hour distribution, languages, recent PRs, and a period_comparison field (recent vs. prior 45 days) that powers the 1:1 Prep Sheet.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Org or user context for PR search. |
login | string | Required | GitHub username. |
/api/github/workflowsList all GitHub Actions workflows for a repository.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/runsFetch workflow runs for a specific workflow (last 50 by default).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
workflow_id | number | Required | Workflow ID. |
per_page | number | Optional | Results per page (default 50, max 100). |
/api/github/job-statsPer-job and per-step timing stats for a workflow: avg, p50, p95, max durations, success/failure counts, waterfall data.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
per_page | number | Optional | Runs to sample (default 30). |
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
workflow_id | number | Required | Workflow ID. |
/api/github/team-statsCI-level team stats: per-actor run count, success rate, avg duration, activity by day/hour.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
per_page | number | Optional | Runs to analyse (default 100). |
/api/github/bus-factorBus factor analysis over the last 90 days (up to 300 commits): per module, the smallest number of authors covering 80% of its commits. 1 is critical, 2 a warning.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/org-health-scorecardLeadership rollup across every repo in an org: a composite health score (60% DORA tier + 40% bus-factor risk), risk band, and throughput trend, sorted worst-first.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org | string | Required | Organization slug. |
limit | number | Optional | Repos to analyse (default 10, max 20 — this is an expensive fan-out). |
/api/github/team-workload-riskTeam-wide people-risk signals for a repo: after-hours/weekend commit patterns, activity cliffs, and concurrent open-PR overload, per contributor. A conversation-starter signal, not a verdict. Hours and weekdays are read in the org workday (Settings → Team insights; default Asia/Saigon 08:00–19:00). Without days: the last 42 days. With days=30|90: that window, plus partial (the commit page cap was reached; no activity cliff then), thresholds, workday, and is_bot / unlinked_name / linked_logins on each row. Account links are applied in both modes.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
days | number | Optional | 30 or 90: the Team insights window. |
/api/github/security-scanStatic analysis of workflow YAML files for security anti-patterns. Returns findings grouped by severity.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/audit-logCommit history for all .github/workflows/*.yml files, sorted by date.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | number | Optional | Commits to return (default 30). |
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/repo-summaryLightweight per-repo summary — default branch, latest run status, workflow count, and health signal. Called lazily as repository rows enter the viewport.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/rate-limitCurrent GitHub API rate-limit status for the authenticated user. Calls GET /rate_limit, which GitHub excludes from rate-limit accounting — checking it is always free.
/api/github/runner-statsPer-runner job counts, durations, and failure rates aggregated across a repo's recent completed workflow runs.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
per_page | number | Optional | Runs to analyse (default 30, max 50). |
/api/cron/syncScheduled background sync, triggered daily by Vercel Cron. Re-syncs every repo tracked in sync_cursors and sends pending digest-channel alert emails. Requires Authorization: Bearer $CRON_SECRET — not callable from the browser.
/api/github/run-detailsJob and step breakdown for a single workflow run: per-job status, timing, and step-level detail.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
run_id | number | Required | Workflow run ID. |
/api/github/open-pr-healthOpen pull-request health for a repository: age, review rounds, draft state, and awaiting-review flags per PR.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
/api/github/org-overviewAggregated org-level metrics across all active repositories — totals, active-repo count, and per-repo summaries. Expensive multi-request call (cached 15 min).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org | string | Required | Organization slug. |
limit | number | Optional | Max repositories to analyse. |
/api/github/org-reposList all repositories in an organization.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org | string | Required | Organization slug. |
/api/github/orgsList organizations the authenticated user belongs to.
/api/github/billingGitHub Actions billing for the authenticated user or an org: minutes used, paid minutes, included minutes, and per-OS breakdown.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org | string | Optional | Organization slug; omit for the authenticated user. |
/api/github/billing/cost-analysisDetailed GitHub Actions cost breakdown via the Enhanced Billing API — per-product/SKU usage and spend for a given month. Some org/account combinations require fine-grained PAT permissions.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org | string | Required | Organization slug. |
year | number | Optional | Billing year (defaults to current). |
month | number | Optional | Billing month 1–12 (defaults to current). |
/api/db/syncTrigger incremental sync of GitHub workflow runs to the database. Checks alert rules after sync completes.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
org | string | Optional | Limit sync to a specific org. |
/api/db/runsHistorical workflow runs from the Neon database (not the GitHub API). Requires DATABASE_URL; returns 0 results if the DB has no data for the repo yet.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Required | Repository name. |
limit | number | Optional | Max rows to return. |
offset | number | Optional | Pagination offset. |
conclusion | string | Optional | Filter by run conclusion (e.g. failure). |
/api/db/trendsAggregated historical trend data from the Neon database — daily rollups for charts, quarterly summaries for year-over-year, or org-wide daily trends.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner (or org login for org trends). |
repo | string | Optional | Repository name (omit for org trends). |
type | string | Optional | daily (default), quarterly, or org. |
days | number | Optional | Window for daily rollups. |
quarters | number | Optional | Number of quarters for quarterly summaries. |
/api/db/working-habitsWorking habits from the database: per-person commit and pull-request size in merged pull requests, oversized commits and pull requests, thresholds, and sync coverage. Needs the workingHabits feature to see anyone; without it, a signed-in user may read only their own login. Returns available:false without DATABASE_URL and untrackedRepo:true for a repository GitDash does not sync. With the grant, account links merge a person's logins (linkedLogins); your own view without the grant is always your own login only.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner. |
repo | string | Optional | Repository name (omit for every tracked repository of the owner). |
login | string | Optional | Narrow to one person. Required without the workingHabits grant, and must be your own login. |
days | number | Optional | 30 (default) or 90, by merge date. |
/api/github/create-issueFile a GitHub issue with the signed-in user's token (used by 'File anomaly as GitHub issue'). Needs the githubIssueFromAnomaly feature; limited to 5 per hour per IP.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | (body) Repository owner. |
repo | string | Required | (body) Repository name. |
title | string | Required | (body) Issue title, up to 256 characters. |
body | string | Optional | (body) Issue body, up to 10,000 characters. |
/api/admin/usersOrganization mode, admin only. Users who have signed in, with their groups and last-seen time.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
q | string | Optional | Filter by login. |
group | string | Optional | Only users in this group. |
limit | number | Optional | Page size (default 100). |
offset | number | Optional | Page offset. |
/api/admin/users/[githubId]/groupsOrganization mode, admin only. Replace a user's groups (audited). Refused with 409 if it would leave no admin.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
groups | string[] | Required | (body) Any of admin, devops, security, dev, pm. |
/api/admin/permissionsOrganization mode, admin only. The group × feature matrix and whether enforcement is on.
/api/admin/permissionsOrganization mode, admin only. Grant or revoke one feature for one group (audited). The admin group has every feature and is not editable.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
group | string | Required | (body) devops, security, dev or pm. |
flag | string | Required | (body) Feature key, e.g. dora. |
granted | boolean | Required | (body) true to grant, false to revoke. |
/api/admin/auditOrganization mode, admin only. Access changes, newest first.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | number | Optional | Entries to return (default 50). |
before | number | Optional | Return entries older than this id. |
/api/cron/sync-pr-factsNightly pull-request sync for the people-metric alert rules. Authenticated by the CRON_SECRET bearer token.
/api/cron/sync-commit-factsNightly working-habits sync at 04:47 UTC: stores the commits of merged pull requests from the last 90 days with their size, then evaluates oversized_commit_pct alert rules. Stops starting new work after 240 s; the rest continues the next night. Authenticated by the CRON_SECRET bearer token.
/api/settings/working-habitsOrganization mode, admin only. Working-habits thresholds in effect (files and lines per commit, commits per pull request). PUT saves them.
/api/settings/teamOrganization mode, admin only. The org workday in effect — time zone (IANA name) and hours — that decides after-hours and weekend commits. PUT { timezone, start, end } saves it; standalone deployments use the default, Asia/Saigon 08:00–19:00.
/api/admin/identity-linksOrganization mode, admin only. Account links (alias → main login) and pairs marked as different people. POST { alias, primary } links (a main login that is itself an alias resolves to its main login; aliases of the alias move along); DELETE ?alias= unlinks. Every change is in the audit log, one row per affected login. Links change numbers only, never access; there is no non-admin endpoint.
/api/admin/identity-links/distinctOrganization mode, admin only. Body { a, b }: these two logins are different people, so Team insights never suggests linking them. DELETE ?a=&b= undoes it.
/api/alertsList alert rules, optionally filtered by scope. Set events=1 to also return the 50 most recent alert events. In organization mode non-admins only see rules and events for repositories and orgs their own token can see, with delivery destinations hidden.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
scope | string | Optional | Filter to a scope, e.g. repo:owner/name. |
events | string | Optional | Set to 1 to include recent alert events. |
/api/alertsCreate an alert rule. metric="leadership_digest" creates a Weekly Leadership Digest instead of a threshold rule — scope must be org:X, and threshold/window_hours are ignored (sent every Monday, no cadence to configure).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
scope | string | Required | (body) Rule scope, e.g. repo:owner/name or org:myorg. |
metric | string | Required | (body) Metric to watch. |
threshold | number | Required | (body) Threshold that triggers the alert. |
window_hours | number | Optional | (body) Evaluation window (default 24). |
channel | string | Optional | (body) Delivery channel (default browser). |
destination | string | Optional | (body) Email address for email delivery. |
/api/alertsUpdate an existing alert rule — enable/disable or change threshold, window, or destination. Admin only in organization mode (as are POST and DELETE).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | number | Required | (body) Alert rule ID. |
/api/alertsDelete an alert rule.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | number | Required | Alert rule ID. |
/api/alerts/testSend a test alert for a rule without a real threshold breach (uses a synthetic value of 1).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
rule_id | number | Required | (body) Alert rule ID to test. |
/api/webhooks/githubReceive GitHub workflow_run webhook events and upsert runs into the database. Authenticated by HMAC-SHA256 signature against GITHUB_WEBHOOK_SECRET — no session required. Rejects all requests if the secret is unset (fail-safe).
/api/ai/statusCapability probe for the AI layer. Returns { enabled, providers } — which providers have a key configured, never the key material. Not rate-limited (no LLM call).
/api/ai/insightsLLM synthesis of a repository's or org's metrics. Returns { ok, provider, model, generated_at, cached, partial, content: { summary, bullets, actions } }. 503 when no provider key is configured or the provider is unavailable; 429 when rate-limited (20/min per token) or the daily token budget is spent. Prompts are built from an allowlisted, metrics-only snapshot — never code, logs, or commit messages.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Optional | Repository owner (repo surface — pair with repo) |
repo | string | Optional | Repository name (repo surface) |
org | string | Optional | Organisation login (org surface — takes precedence over owner/repo) |
refresh | 1 | Optional | Bypass the cached generation. Still rate-limited. |
/api/ai/anomaly-explanationExplain a workflow metric's statistical outliers from surrounding metadata (baseline stats, workflow-file change dates, trigger mix). Returns { ok, provider, model, outlier_count, content: { explanation, check } }. 404 when the metric has no outliers to explain; 503 when unconfigured or unavailable; 429 when rate-limited (20/min per token). Never reads run logs.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner |
repo | string | Required | Repository name |
workflow_id | number | Required | Workflow ID |
metric | duration | queue_wait | Required | Which metric's outliers to explain. Validated against a literal allowlist — arbitrary values are rejected, never forwarded to a prompt. |
/api/ai/root-causeRanked hypotheses for why a workflow is failing, inferred from failed job/step names, timing shifts, trigger and branch clustering, and workflow-file change dates. Returns { ok, provider, model, failure_count, partial, content: { hypotheses[] } } where each hypothesis carries rank, evidence, confidence (high|medium|low) and next_step. Returns content: null below 3 recent failures — enforced server-side, no provider call. Rate-limited to 10/min per token, half the other AI surfaces. Never reads run logs.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner |
repo | string | Required | Repository name |
workflow_id | number | Required | Workflow ID |
/api/github/issuesIssue and triage health. Returns { open_count, opened_in_period, closed_in_period, backlog_delta, median_days_to_close, p90_days_to_close, stale_count, unlabelled_count, unanswered_count, age_buckets[], top_labels[], assignee_load[], neglected[], oldest_open, total_analysed, partial }. Pull requests are excluded — GitHub's issues endpoint returns both, and counting PRs would report delivery throughput as triage throughput.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner |
repo | string | Required | Repository name |
days | number | Optional | Window in days, 7-90. Defaults to 30. |
/api/github/deploymentsMeasured delivery metrics from GitHub's Deployments API. Returns { source, production_environment, deploys_per_day, change_failure_rate_pct, mttr_hours, mttr_samples, by_environment[], recent[], partial, all_time_count, newest_deployment_at }. source is "deployments" when the window has data, "stale" when the repo has deployment history but none inside the window, and "none" when it has never recorded one — the caller keeps its release/PR estimates for the latter two rather than being handed zeros. all_time_count and newest_deployment_at describe history at any age, so a stale window can state how much exists and when it stopped. Rates exclude pending and in-progress deploys, and return null rather than 0% when nothing is conclusive.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner |
repo | string | Required | Repository name |
/api/github/security-alertsGitHub's own security findings: Dependabot, code scanning and secret scanning alerts. Returns { sources, alerts[], counts, total_open, oldest_open_days, partial, needs_scope } where each source carries its own status (ok | forbidden | not_enabled | error) plus 90-day fix count and mean time to remediate. A classic PAT with repo reads all three; no security_events scope is required. A 403 is classified by its response body — a disabled feature becomes not_enabled, a genuine permission failure becomes forbidden and sets needs_scope — so an unreadable source is never reported as a clean one, and a switched-off one never prompts a pointless token change.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
owner | string | Required | Repository owner |
repo | string | Required | Repository name |
/api/settings/aiCurrent AI provider override. Returns { configurable, mode, enabled, provider, model, base_url, api_key_hint, has_key, updated_by, updated_at, effective_source, env_providers, db_available }. The API key is never returned — only a masked hint. configurable is false in standalone mode, where the section is hidden and environment defaults apply.
/api/settings/aiSave an AI provider override. Body: { enabled, provider ("bailian"|"gemini"|"qwen"), model, base_url, api_key? }. Omitting api_key preserves the stored one; the key is encrypted before storage. base_url must be https. 403 in standalone mode, 503 when no database is configured. A configured override is used exclusively — server keys are never a fallback behind it.
/api/settings/emailCurrent email delivery configuration. Returns { enabled, provider, from_address, api_key_hint, has_key, updated_by, updated_at, effective_source, db_available }. The API key itself is never returned — only a masked hint. effective_source reports whether Settings, environment variables, or nothing is actually in effect.
/api/settings/emailSave email delivery configuration. Body: { enabled, provider ("resend"|"sendgrid"), from_address, api_key? }. Omitting api_key preserves the stored one. The key is encrypted with AES-256-GCM before storage. Rejects enabling without a key or from address. 503 when no database is configured.
/api/settings/email/testSend a test email through the currently-resolved provider to verify configuration. Body: { to }. Returns the provider's own error verbatim on failure (bad key, unverified sender) since it is actionable and contains no secret. Rate-limited to 3/min per token.
/api/healthLiveness/readiness probe. Returns {"status":"ok"} with no authentication. Used by Kubernetes and load balancers.
/api/demoSanitized fixture data for demo mode. No authentication required — the payload contains no real credentials.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
resource | string | Required | repos, runs, or summary. |
repo | string | Optional | Repository name for run/summary fixtures. |
count | number | Optional | Number of synthetic runs to generate. |
/api/auth/setupStandalone mode: validate the submitted PAT and store it in an encrypted session cookie. Rate-limited.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
pat | string | Required | (body) GitHub Personal Access Token. |
/api/auth/setupStandalone mode: clear the stored PAT (sign out).
/api/auth/loginOrganization mode: begin the GitHub OAuth flow (redirects to GitHub). Rate-limited.
/api/auth/callbackOrganization mode: OAuth redirect target — verifies state, exchanges the code, and creates the session.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
code | string | Required | OAuth authorization code (set by GitHub). |
state | string | Required | CSRF state token (set by GitHub). |
/api/auth/logoutDestroy the session cookie and sign the user out.
/api/auth/meReturn the current session identity (login, mode), or 401 if unauthenticated.