API

Start scans and read findings from scripts, CI or an AI agent.

Documentation

Quickstart

Sign up to grab your key and put it in an environment variable. Then three calls: start a scan, wait for it, read its findings.

API access is included with Starter and Pro.

export SETREPO_API_KEY=sr_live_...   # create your key in the SetRepo dashboard

# 1. Start a scan
SCAN_ID=$(curl -s "https://setrepo.com/v1/scans" \
  -H "Authorization: Bearer $SETREPO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"repo_url": "https://github.com/you/app", "type": "quick"}' | jq -r .scan_id)

# 2. Wait until it's complete or failed
until curl -s "https://setrepo.com/v1/scans/$SCAN_ID" -H "Authorization: Bearer $SETREPO_API_KEY" \
  | jq -e '.status == "complete" or .status == "failed"' > /dev/null; do sleep 5; done

# 3. Read the findings
curl -s "https://setrepo.com/v1/scans/$SCAN_ID/findings?severity=critical,high" \
  -H "Authorization: Bearer $SETREPO_API_KEY"

Base URL: https://setrepo.com/v1

Authentication

Send your key on every request: Authorization: Bearer sr_live_...

Keep it secret, like a password. Never commit it to a repository; read it from an environment variable or your CI's secrets.

You can rotate a key at any time: create a new one, switch over, then revoke the old one. A revoked key stops working at once.

Endpoints

POST/v1/scans· Start a scan

Starts the scan at once and returns its id. A public repo link goes as JSON; a zip goes as multipart/form-data. Quota is checked and charged now (see Quota).

parametertype
repo_urlstringA public GitHub, GitLab or Bitbucket repo, or a branch or folder in one (JSON).
filefileA .zip of the project folder, instead of repo_url (multipart).
type"quick" | "deep"Default quick. Deep adds the AI review and uses the allowance.
project_iduuidZip only: rescan this zip project. Omit to make a new one.
project_namestringZip only: the new project's name. Default: the file name.
Repo link
curl -s "https://setrepo.com/v1/scans" \
  -H "Authorization: Bearer $SETREPO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"repo_url":"https://github.com/you/app","type":"deep"}'
Zip upload
curl -s "https://setrepo.com/v1/scans" \
  -H "Authorization: Bearer $SETREPO_API_KEY" \
  -F "file=@app.zip" \
  -F "type=quick" \
  -F "project_name=My app"
Response · 202 Accepted
{
  "scan_id": "3f0c9a52-6d1e-4b8a-9c57-2e41b0d7a913",
  "status": "queued"
}

GET/v1/scans/{scan_id}· Get a scan

Poll every few seconds. status is queued, running, complete or failed (with error.code). Once complete: the grade and open findings by severity.

SCAN_ID=3f0c9a52-6d1e-4b8a-9c57-2e41b0d7a913
curl -s "https://setrepo.com/v1/scans/$SCAN_ID" \
  -H "Authorization: Bearer $SETREPO_API_KEY"
Response · 200 OK
{
  "scan_id": "3f0c9a52-6d1e-4b8a-9c57-2e41b0d7a913",
  "status": "complete",
  "type": "deep",
  "project_id": "8b2d7c10-41f3-4e0a-a6b5-93c1e2f4d806",
  "source": "https://github.com/you/app",
  "grade": "C",
  "counts": {
    "critical": 0,
    "high": 2,
    "medium": 5,
    "low": 3
  },
  "created_at": "2026-10-26T18:56:10Z",
  "completed_at": "2026-10-26T19:02:44Z",
  "error": null
}

GET/v1/scans/{scan_id}/findings· List findings

The open findings of a complete scan, most severe first, in a compact shape an agent can act on. Findings marked as false positives in the dashboard are left out.

parametertype
severitystringComma-separated: critical,high,medium,low. Default: all.
limit1–200Page size. Default 50.
offsetintegerWhere the page starts. Use next_offset from the last page; null means it was the last.
SCAN_ID=3f0c9a52-6d1e-4b8a-9c57-2e41b0d7a913
curl -s "https://setrepo.com/v1/scans/$SCAN_ID/findings?severity=critical,high&limit=50" \
  -H "Authorization: Bearer $SETREPO_API_KEY"
Response · 200 OK
{
  "scan_id": "3f0c9a52-6d1e-4b8a-9c57-2e41b0d7a913",
  "masked": false,
  "total": 2,
  "limit": 50,
  "offset": 0,
  "next_offset": null,
  "findings": [
    {
      "id": "c51e0f6a-93b2-4d7e-8f14-6a0b2c9d3e71",
      "severity": "high",
      "category": "access_control",
      "file": "app/api/orders.py",
      "line": 42,
      "title": "Order lookup doesn't check the owner",
      "fix": "Load the order with both its id and the signed-in user's id, and return 404 when it isn't theirs."
    }
  ]
}

GET/v1/projects· List projects

The account's projects (one per app), most recently scanned first, with each one's newest complete scan.

curl -s "https://setrepo.com/v1/projects" \
  -H "Authorization: Bearer $SETREPO_API_KEY"
Response · 200 OK
[
  {
    "id": "8b2d7c10-41f3-4e0a-a6b5-93c1e2f4d806",
    "name": "you/app",
    "source_type": "public_url",
    "source": "https://github.com/you/app",
    "live_url": null,
    "created_at": "2026-10-01T09:12:03Z",
    "last_scanned_at": "2026-10-26T18:56:10Z",
    "last_scan_id": "3f0c9a52-6d1e-4b8a-9c57-2e41b0d7a913"
  }
]

GET/v1/usage· Get usage

Deep scans and project slots used and left this cycle, and when they reset. The same numbers as the dashboard.

curl -s "https://setrepo.com/v1/usage" \
  -H "Authorization: Bearer $SETREPO_API_KEY"
Response · 200 OK
{
  "plan": "starter",
  "scans": {
    "used": 3,
    "limit": 8,
    "remaining": 5,
    "bonus_credits": 0
  },
  "projects": {
    "used": 1,
    "limit": 2,
    "remaining": 1
  },
  "reset_at": "2026-11-16T00:00:00Z"
}

MCP

Use SetRepo inside Claude, Claude Code, Cursor, Codex, Lovable and Replit. Connector URL: https://setrepo.com/mcp. Clients sign in with your SetRepo account; no API key needed.

Setup for each client and the available tools are on the MCP page.

Quota and limits

  • One pool. The API and the dashboard share your deep scans and project slots.
  • Deep scans take one scan when you start them (a large repo takes two). Quick scans are free.
  • Unchanged code is free. A deep rescan of the same code as the project's last deep scan gives its scan back.
  • 60 requests a minute per key. Over that: 429 with Retry-After in seconds.
  • Headers. Every response has X-Scans-Remaining and X-Projects-Remaining.

Errors

Every error looks like {"error": {"code": "...", "message": "..."}}. Branch on the code; show the message.

codestatuswhat to do
invalid_key401Check the key, or create a new one. Revoked keys stop working at once.
api_not_available403Upgrade to Starter or Pro.
project_limit_reached403Delete a project you don't need, or upgrade.
quota_exceeded402 / 429402: no deep scans left; run a quick scan or wait for the reset. 429: daily fair-use limit; try later.
rate_limited429Wait Retry-After seconds, then retry.
invalid_request400 / 422Fix the field the message names.
not_found404Check the scan id; it must be one of your account's.
scan_not_complete409Keep polling until status is complete.
service_unavailable503Retry in a minute.
deep_not_availablefailed scanRun a quick scan: this code has nothing for the AI review.
scan_not_supportedfailed scanThe code is too large, or isn't the project's app. Scan a smaller folder or a new project.
scan_failedfailed scanRun it again. If it keeps failing, contact support.

Privacy and data

  • Your code. We download a copy to scan it and delete it when the scan finishes or fails. A zip for a quick scan is kept up to 24 hours, so you can upgrade it to a deep scan, then deleted.
  • No training. SetRepo doesn't train AI models on your code. A deep scan sends the relevant parts to Anthropic for the AI review, with secrets removed; under Anthropic's commercial terms it isn't used for training.
  • What we keep. Findings (title, description, file path, lines, fix; secret values removed) and scan details: the repo link and commit, the detected stack, file names with content hashes, and your app's routes. Never the code itself.
  • Who sees it. Only your account. Our team can open a scan in our admin tools, only to help you, to look into abuse, to keep the service running and to make our checks more accurate.
  • Your keys are stored as a hash. We can't show a key again, so copy it when you create it.

Reports stay until you delete them or your account. More in the Privacy Policy and Terms.

Fair use

  • Only scan code you own or have permission to scan.
  • Don't use the API to attack or overload anything, or to get around the limits.
  • A key belongs to your account. Don't share it, sell it or let others use it, and revoke it if it leaks.

Support

Questions or problems: support@setrepo.com. Include the scan id if it's about a scan.

OpenAPI schema