POST /scan/bulk

Synchronous bulk-scan endpoint. Accepts up to 50 SKILL.md files in one call — by URL, by pre-fetched content, or a mix. Built primarily for CI integrations like the SkillOx GitHub Action; same scanner engine as the single-skill POST /scan, just batched + sync.

Need to scan one skill at a time? Use POST /scan — it's queued + Turnstile-gated for anonymous browser callers. /scan/bulk is sync, headless, and rate-limited per IP.

Request

POST https://api.skillox.io/scan/bulk
Content-Type: application/json

{
  "urls": [
    "https://raw.githubusercontent.com/foo/bar/main/SKILL.md"
  ],
  "files": [
    {
      "path": "skills/leaky/SKILL.md",
      "content": "---\nname: leaky\n---\n…"
    }
  ],
  "persist": false
}

Fields

Combined urls + files cannot exceed 50 items per request. At least one must be present.

Response · 200 OK

200 OK

{
  "summary": {
    "total": 2,
    "passed": 1,
    "failed": 1,
    "caution": 0,
    "errors": 0
  },
  "results": [
    {
      "ok": true,
      "input": { "kind": "url", "url": "https://raw.githubusercontent.com/…/SKILL.md" },
      "grade": "A",
      "score": 95,
      "skillName": "frontend-design",
      "skillVersion": null,
      "findingsCount": 1,
      "findings": [
        { "ruleId": "no-manifest", "severity": "med", "title": "No capability manifest declared", "line": null }
      ],
      "scanDurationMs": 1
    },
    {
      "ok": true,
      "input": { "kind": "file", "path": "skills/leaky/SKILL.md" },
      "grade": "F",
      "score": 0,
      "skillName": "leaky",
      "skillVersion": "0.1.0",
      "findingsCount": 5,
      "findings": [
        { "ruleId": "env-var-harvesting", "severity": "crit", "title": "Skill references secret env var $ANTHROPIC_API_KEY", "line": 9 }
      ],
      "scanDurationMs": 0
    }
  ],
  "remaining": 49
}

Summary fields

Per-item result fields

Limits

Errors

Per-item failures (URL fetch failed, content too large, scan errored) don't fail the whole call — they come back as { ok: false, error: "fetch_failed" | "content_too_large" | "scan_failed" } entries in the results array so successful items still return.

If you're using this from GitHub Actions, the SkillOx Action wraps this endpoint with PR annotations + summary comments — drop in two lines of YAML and you're done.