Skip to content

Documentation

Everything you need to secure your AI-built projects

REST API

Integrations

REST API reference

Use the authenticated BoringSec REST API to queue URL scans, inspect their status and results, scan code and GitHub repositories, generate fix rules, and configure webhooks with your bsk_ API key.

Authentication

All requests require an API key in the Authorization header:

http
Authorization: Bearer bsk_your_api_key_here
API keys use the bsk_ prefix. Manage keys at /api-keys. Keys are stored as SHA-256 hashes and scoped to specific permissions.

Scanning

POST/api/v1/scanPro+

Set async=true for the modern HTTP 202 queue contract (requires scan:write and scan:read), then poll the returned status link. Compatibility: clients that omit async are still queued, but the request waits up to 90 seconds and returns the legacy completed report (HTTP 201) when ready.

Request body

json
{ "url": "https://example.com", "async": true }

Response

json
{
  "scan": {
    "id": "cln...",
    "url": "https://example.com",
    "status": "PENDING",
    "reused": false,
    "links": {
      "status": "/api/v1/scans/cln.../status",
      "result": "/api/v1/scans/cln...",
      "fullResult": "/api/v1/scans/cln.../full"
    }
  },
  "message": "Scan queued. Poll the status endpoint for progress and results."
}
POST/api/v1/scans/asyncBusiness+

Business-tier alias for the same durable queue contract, with optional webhookUrl and request metadata. SCAN_COMPLETED means the base report is ready; isolated Nuclei, ZAP, and Medusa jobs may still be queued or running and never delay that callback. It requires scan:write and scan:read; existing integrations may keep using it.

Request body

json
{
  "url": "https://example.com",
  "webhookUrl": "https://your-app.example/boringsec-webhook",
  "metadata": { "build": "2026.07.10" }
}
POST/api/v1/scan/codePro+

Scan code files for hardcoded secrets, unsafe patterns, and misconfigurations. Supports 30+ detection patterns.

Request body

json
{
  "files": [
    {
      "filename": "src/app.ts",
      "content": "const apiKey = 'sk_live_abc123';"
    }
  ]
}

Response

json
{
  "summary": {
    "totalFiles": 1,
    "totalFindings": 1,
    "critical": 1
  },
  "findings": [
    {
      "file": "src/app.ts",
      "line": 1,
      "patternId": "stripe-key-in-code",
      "severity": "critical",
      "title": "Stripe Secret Key in Code",
      "recommendation": "Rotate and store server-side only."
    }
  ]
}
POST/api/v1/scan/projectBusiness+

Scan a full project structure: dependencies, .env files, sensitive file detection.

Request body

json
{
  "files": [{ "path": ".env" }, { "path": "src/index.ts" }],
  "packageJson": { "dependencies": { "lodash": "4.17.0" } },
  "envExample": "API_KEY=sk_live_real_key"
}
POST/api/v1/scan/githubPro+

Scan a GitHub repository for committed secrets, vulnerable dependencies, and auth misconfigurations.

Request body

json
{ "repository": "owner/repo" }

Scan results

GET/api/v1/scans/{id}Pro+

Get full scan results by ID.

GET/api/v1/scans/{id}/statusPro+

Poll the durable links.status URL. COMPLETED means the base report is ready, not necessarily that the isolated Nuclei, ZAP, and Medusa jobs are terminal. Continue while deepScan.active=true (honor Retry-After); inspect each job for queued, running, retry_scheduled, completed, failed, or authorization_required. Stop when deepScan.terminal=true. Legacy scans may omit deepScan instead of guessing not_requested.

Response

json
{
  "scan": {
    "id": "cln...",
    "status": "COMPLETED",
    "progress": 100,
    "score": 92,
    "grade": "A+",
    "links": {
      "status": "/api/v1/scans/cln.../status",
      "result": "/api/v1/scans/cln...",
      "fullResult": "/api/v1/scans/cln.../full"
    },
    "deepScan": {
      "status": "queued",
      "active": true,
      "terminal": false,
      "jobs": [
        {
          "category": "nuclei",
          "status": "running",
          "attemptCount": 1,
          "maxAttempts": 3,
          "nextAttemptAt": null
        },
        {
          "category": "zap",
          "status": "retry_scheduled",
          "attemptCount": 1,
          "maxAttempts": 3,
          "nextAttemptAt": "2026-07-11T08:05:00.000Z"
        },
        {
          "category": "medusa",
          "status": "queued",
          "attemptCount": 0,
          "maxAttempts": 3,
          "nextAttemptAt": null
        }
      ]
    }
  }
}
GET/api/v1/scans/{id}/compliance/{framework}Business+

Get compliance report. Frameworks: PCI_DSS_4, GDPR, SOC2, HIPAA, ISO27001.

Developer tools

GET/api/v1/usagePro+

Get current usage stats, remaining quota, subscription tier, and available features.

Response

json
{
  "tier": "PRO",
  "scans": { "used": 4, "limit": 10, "remaining": 6 },
  "apiCalls": { "remaining": 87, "limit": 100 },
  "features": { "githubScanning": true, "compliance": false }
}
GET/api/v1/fix-suggestions/{issueCode}Pro+

Get fix prompts optimized for AI coding tools (Cursor, Lovable, Bolt, Claude Code, v0, Windsurf, Replit).

Response

json
{
  "issueCode": "supabase-rls",
  "builtin": [{ "title": "Enable RLS", "prompts": { "cursor": "..." } }],
  "community": [{ "title": "...", "upvotes": 12 }]
}
POST/api/v1/generate-rulesPro+

Generate .cursorrules or AGENTS.md files to make AI coding sessions security-aware.

Request body

json
{
  "format": "both",
  "stack": "nextjs-supabase",
  "scanId": "cln..."
}

Response

json
{
  "cursorrules": "# BoringSec Security Rules\n...",
  "agentsMd": "# BoringSec Security Context\n..."
}

Domains

GET/api/v1/domainsPro+

List all domains.

POST/api/v1/domainsPro+

Add a new domain.

Request body

json
{ "url": "https://example.com" }
GET/api/v1/domains/{id}/historyBusiness+

Scan history for a domain.

Webhooks

GET/api/v1/webhooksBusiness+

List webhook endpoints.

POST/api/v1/webhooksBusiness+

Create a webhook. Events: SCAN_COMPLETED, SCORE_CHANGED, ISSUE_NEW_CRITICAL, SSL_EXPIRING.

Request body

json
{
  "url": "https://your-app.com/webhook",
  "events": ["SCAN_COMPLETED", "ISSUE_NEW_CRITICAL"]
}