PatchFlow API · v1

Repo status

The single endpoint a SIEM needs: open CVEs, in-flight patch PRs, and the 30-day merge rollup for one watched repository. No token required.

GET
application/json
Public
URL pattern
Both path segments are validated against /^[A-Za-z0-9._-]+$/ (1–100 chars). Requests that don't match are rejected with 400 before any data lookup.

GET https://<host>/api/v1/repos/{owner}/{name}/status

  • owner — GitHub org or user slug (1–100 chars).
  • name — repository name (1–100 chars).
Authentication
Token-free by design.

No authentication is required. This endpoint is intentionally public so SIEM platforms can poll without provisioning or rotating API tokens. Rate limiting and abuse controls are applied at the edge; clients should respect standard back-off signals (HTTP 429 + Retry-After) rather than opening many concurrent connections.

HTTP semantics
Status codes the handler emits.
StatusWhenBody
200Repo exists and is enabled.RepoStatusResponse (JSON object).
400Either path segment fails the regex / length check.{ "error": "invalid path" }
404Repo is not in the watch list.{ "error": "Repo {owner}/{name} not found" }
Response shape
Schemas live in src/lib/contracts/repo-status.ts (`RepoStatusResponse`). Integrate against those, not a hand-written copy.

repo

{ owner, name, defaultBranch, enabled, riskScore, lastCheckedAt }

  • owner — GitHub org or user, copied from the URL path.
  • name — repository name, copied from the URL path.
  • defaultBranch — the branch GitHub reports as default.
  • enabled — whether the watcher is currently polling this repo.
  • riskScore— integer 0–100, nullable; the watcher's blended risk for this repo.
  • lastCheckedAt — ISO-8601 timestamp; nullable when the watcher has never run.

openCves

Array of { ghsaId, cveId, cweIds, severity, summary, publishedAt, repoFullName }.

  • ghsaId — GitHub Security Advisory id (e.g. GHSA-abcd-…).
  • cveId — nullable; not every advisory has a CVE assignment.
  • cweIds — list of CWE ids; empty array if none.
  • severity — publisher severity label.
  • summary — short advisory summary.
  • publishedAt — ISO-8601 timestamp.
  • repoFullName — denormalised {owner}/{name} so SIEM consumers don't have to thread the URL path back through their correlation.

patchArtifactSummary

{ inFlight, mergedLast30d, latestMergedAt }

  • inFlight — count of patch artifacts whose PR is open but not yet merged.
  • mergedLast30d — count of patches that merged in the trailing 30-day window.
  • latestMergedAt — ISO-8601 timestamp of the most recent merge across the artifact set; null when none has ever merged.
Examples
Three idiomatic copies — the body fetched is identical in all three.

curl

curl -sS -X GET 'https://${HOST}/api/v1/repos/acme-co/widgets/status' \
  -H 'Accept: application/json' \
  -H 'User-Agent: patchflow-siem-poll/1.0'

fetch (browser / Deno / Node 22+)

const response = await fetch(`https://${HOST}/api/v1/repos/acme-co/widgets/status`, {
  method: 'GET',
  headers: {
  'Accept': 'application/json',
  'User-Agent': 'patchflow-siem-poll/1.0',
},
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const body = await response.json();

Python · requests

import os
import requests

host = os.environ['PATCHFLOW_HOST']  # e.g. https://api.patchflow.dev
url = f"{host}/api/v1/repos/acme-co/widgets/status"
headers = {'Accept': 'application/json'}

response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
print(response.json())
Sample response
A live call against /api/v1/repos/acme-co/widgets/status returns the JSON below. The body is constructed and zod-validated once at module load in src/lib/business/docs/repo-status-sample.ts, so the doc cannot drift from the live contract.
{
  "repo": {
    "owner": "acme-co",
    "name": "widgets",
    "defaultBranch": "main",
    "enabled": true,
    "riskScore": 68,
    "lastCheckedAt": "2026-07-25T08:14:00.000Z"
  },
  "openCves": [
    {
      "ghsaId": "GHSA-abcd-1234-efgh",
      "cveId": null,
      "cweIds": [],
      "severity": "high",
      "summary": "Prototype pollution in utils.merge allows attackers to inject properties on Object.prototype.",
      "publishedAt": "2026-07-23T17:02:00.000Z",
      "repoFullName": "acme-co/widgets"
    },
    {
      "ghsaId": "GHSA-wxyz-9876-lmno",
      "cveId": "CVE-2026-31415",
      "cweIds": [
        "CWE-79",
        "CWE-1321"
      ],
      "severity": "critical",
      "summary": "Reflected XSS in the legacy /search route renders attacker-controlled HTML without escaping.",
      "publishedAt": "2026-07-19T12:45:00.000Z",
      "repoFullName": "acme-co/widgets"
    }
  ],
  "patchArtifactSummary": {
    "inFlight": 1,
    "mergedLast30d": 1,
    "latestMergedAt": "2026-07-22T19:31:00.000Z"
  }
}