{"openapi":"3.1.0","info":{"title":"SetRepo API","description":"Scan code for security issues and read the findings: from scripts, CI, or an AI\nagent (MCP).\n\n**Auth**: `Authorization: Bearer sr_live_...`, a key from the API page in the dashboard.\nStarter and Pro plans.\n\n**Flow**: `POST /v1/scans` starts the scan: it's queued at once and runs as soon as the code\nhas been fetched and measured, with every check that applies. Poll `GET /v1/scans/{scan_id}`\nevery few seconds until `status` is `complete` or `failed` (polling only reads), then\n`GET /v1/scans/{scan_id}/findings`.\n\n**Quota**: the same as the dashboard's, one pool for both. A deep scan takes one scan of the\nallowance when it's created (a large repo takes a second once measured); it's given back if\nthe code is unchanged since the project's last deep scan (served from that report) or the scan\ncan't run. Quick scans don't use the allowance. Every response carries `X-Scans-Remaining`\n(deep scans left this cycle) and `X-Projects-Remaining` (project slots left).\n\n**Limits**: 60 requests a minute per key; over it, 429 with `Retry-After` (seconds).\n\n**Errors**: `{\"error\": {\"code\": \"...\", \"message\": \"...\"}}`. `invalid_key` (401),\n`api_not_available` (403), `project_limit_reached` (403), `quota_exceeded` (402 or 429),\n`rate_limited` (429), `not_found` (404), `invalid_request` (422).","version":"1"},"paths":{"/scans":{"post":{"tags":["scans"],"summary":"Start a scan","description":"Scan a public repo (JSON) or a zip (multipart/form-data, field `file`). The scan starts\nnow; poll `GET /v1/scans/{scan_id}` until `status` is `complete` or `failed`.\n\n`quick` runs the deterministic checks and doesn't use the allowance. `deep` adds the AI\nreview and takes one deep scan now: a large repo takes a second once it's been measured,\nand the scan comes back if the code is unchanged since the project's last deep scan or the\nscan can't run. A repo link or zip that's new to the account becomes a project, which needs\na free project slot. With credit billing on, read GET /v1/credits/estimate and send\n`max_credits` once the user has authorized it (see the API description).","operationId":"create_scan_scans_post","requestBody":{"content":{"application/json":{"schema":{"properties":{"repo_url":{"type":"string","maxLength":2048,"title":"Repo Url","description":"A public GitHub, GitLab or Bitbucket repo, or a branch or folder in one.","examples":["https://github.com/octo/widgets"]},"type":{"type":"string","enum":["quick","deep"],"title":"Type","default":"quick"},"max_credits":{"anyOf":[{"type":"integer","maximum":2000000000.0,"minimum":0.0},{"type":"null"}],"title":"Max Credits"}},"additionalProperties":false,"type":"object","required":["repo_url"],"title":"CreateScanIn","description":"A public repo by link. To scan a zip, send multipart/form-data instead (see the endpoint)."}},"multipart/form-data":{"schema":{"properties":{"file":{"type":"string","format":"binary","description":"A .zip of the project folder."},"type":{"type":"string","enum":["quick","deep"],"default":"quick"},"max_credits":{"type":"integer","maximum":2000000000.0,"minimum":0.0,"description":"Maximum authorized credit deduction. Read /credits/estimate first."},"project_id":{"type":"string","format":"uuid","description":"Rescan this zip project. Omit to make a new one."},"project_name":{"type":"string","description":"A new project's name (default: the file name)."}},"type":"object","required":["file"]}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanCreated"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"413":{"description":"Request Entity Too Large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}}},"security":[{"HTTPBearer":[]}]}},"/scans/{scan_id}":{"get":{"tags":["scans"],"summary":"Get a scan","description":"Status, and once complete the grade and open findings by severity. Poll every few seconds\nuntil `status` is `complete` or `failed`.","operationId":"get_scan_scans__scan_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Scan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanStatusOut"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Conflict"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Request Entity Too Large"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too Many Requests"}}}},"/scans/{scan_id}/findings":{"get":{"tags":["scans"],"summary":"List findings","description":"The open findings of a complete scan, most severe first. Findings marked as false\npositives in the dashboard are left out, as in the report.","operationId":"list_findings_scans__scan_id__findings_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Scan Id"}},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated: critical,high,medium,low.","examples":["critical,high"],"title":"Severity"},"description":"Comma-separated: critical,high,medium,low."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FindingsPage"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Payment Required"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Conflict"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Request Entity Too Large"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}},"description":"Too Many Requests"}}}},"/projects":{"get":{"tags":["account"],"summary":"List projects","description":"The account's projects (one per app), most recently scanned first.","operationId":"list_projects_projects_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ProjectItem"},"type":"array","title":"Response List Projects Projects Get"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}}},"security":[{"HTTPBearer":[]}]}},"/usage":{"get":{"tags":["account"],"summary":"Get usage","description":"Deep scans and project slots used and left this cycle, and when they reset. Shared with\nthe dashboard: a scan started from either counts once, against the same allowance.","operationId":"usage_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageOut"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorOut"}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"ErrorBody":{"properties":{"code":{"type":"string","title":"Code","examples":["quota_exceeded"]},"message":{"type":"string","title":"Message"}},"type":"object","required":["code","message"],"title":"ErrorBody"},"ErrorOut":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"type":"object","required":["error"],"title":"ErrorOut"},"FindingItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"severity":{"type":"string","enum":["critical","high","medium","low"],"title":"Severity"},"category":{"type":"string","title":"Category","description":"access_control, business_logic, secrets, injection, dependencies, infra_config, seo, accessibility or compliance.","examples":["access_control"]},"file":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File"},"line":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Line"},"title":{"type":"string","title":"Title"},"fix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fix","description":"How to fix it, written so it can be handed to a coding agent."}},"type":"object","required":["id","severity","category","file","line","title","fix"],"title":"FindingItem"},"FindingsPage":{"properties":{"scan_id":{"type":"string","format":"uuid","title":"Scan Id"},"masked":{"type":"boolean","title":"Masked","description":"A free quick scan run before the account subscribed: file, line and fix are hidden on all but its top findings."},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset"},"findings":{"items":{"$ref":"#/components/schemas/FindingItem"},"type":"array","title":"Findings"}},"type":"object","required":["scan_id","masked","total","limit","offset","next_offset","findings"],"title":"FindingsPage"},"ProjectItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"source_type":{"type":"string","enum":["public_url","github_app","zip","url"],"title":"Source Type"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"The repo link or GitHub repo; null for a zip."},"live_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Live Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_scanned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Scanned At"},"last_scan_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Last Scan Id","description":"The newest complete scan."}},"type":"object","required":["id","name","source_type","source","live_url","created_at","last_scanned_at","last_scan_id"],"title":"ProjectItem"},"ProjectsUsage":{"properties":{"used":{"type":"integer","title":"Used"},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Limit"},"remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining"}},"type":"object","required":["used","limit","remaining"],"title":"ProjectsUsage"},"ScanCreated":{"properties":{"scan_id":{"type":"string","format":"uuid","title":"Scan Id"},"status":{"type":"string","enum":["queued","running","complete","failed","needs_action"],"title":"Status"}},"type":"object","required":["scan_id","status"],"title":"ScanCreated"},"ScanStatusOut":{"properties":{"credits":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Credits"},"scan_id":{"type":"string","format":"uuid","title":"Scan Id"},"status":{"type":"string","enum":["queued","running","complete","failed","needs_action"],"title":"Status"},"type":{"type":"string","enum":["quick","deep"],"title":"Type"},"project_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Project Id"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"The repo link, or the upload id of a zip."},"grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grade","description":"A to F, once complete."},"counts":{"anyOf":[{"$ref":"#/components/schemas/SeverityCounts"},{"type":"null"}],"description":"Open findings by severity, once complete."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"error":{"anyOf":[{"$ref":"#/components/schemas/ErrorBody"},{"type":"null"}],"description":"Why a failed scan didn't finish."}},"type":"object","required":["scan_id","status","type","project_id","source","grade","counts","created_at","completed_at"],"title":"ScanStatusOut"},"ScansUsage":{"properties":{"used":{"type":"integer","title":"Used","description":"Deep scans used this cycle (a large repo uses 2). Quick scans are not counted."},"limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Limit","description":"Deep scans per cycle on the plan; null: unlimited."},"remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining","description":"Left this cycle, plus saved scan credits; null: unlimited."},"bonus_credits":{"type":"integer","title":"Bonus Credits"}},"type":"object","required":["used","limit","remaining","bonus_credits"],"title":"ScansUsage"},"SeverityCounts":{"properties":{"critical":{"type":"integer","title":"Critical"},"high":{"type":"integer","title":"High"},"medium":{"type":"integer","title":"Medium"},"low":{"type":"integer","title":"Low"}},"type":"object","required":["critical","high","medium","low"],"title":"SeverityCounts"},"UsageOut":{"properties":{"credits":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Credits"},"plan":{"type":"string","title":"Plan","examples":["starter"]},"scans":{"$ref":"#/components/schemas/ScansUsage"},"projects":{"$ref":"#/components/schemas/ProjectsUsage"},"reset_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reset At","description":"When this cycle ends and the counts reset."}},"type":"object","required":["plan","scans","projects","reset_at"],"title":"UsageOut"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"An API key from the dashboard's API page: `sr_live_...`","scheme":"bearer"}}},"servers":[{"url":"/v1"}]}