API Reference

REST API for programmatic access to SDKWatch projects, scans, and consent records.

Base URLhttps://sdkwatch.com/api

#Authentication

All API requests require an API key in the Authorization header:

bash
curl https://sdkwatch.com/api/projects \
  -H "Authorization: Bearer sdk_your_api_key_here"

Generate an API key in your dashboard under Settings → API Keys. Keep it secret — it has full access to your account.

#Projects

GET/api/projects

List all projects in your account.

json
// Response 200
{
  "projects": [
    {
      "id": "proj_a1b2c3",
      "name": "My Website",
      "domain": "example.com",
      "platform": "web",
      "snippetId": "sdk_a1b2c3d4e5f6",
      "createdAt": "2025-01-15T10:00:00Z",
      "lastScanAt": "2025-02-01T14:30:00Z",
      "complianceScore": 78
    }
  ]
}
POST/api/projects

Create a new project.

json
// Request body
{
  "name": "My App",
  "domain": "example.com",
  "platform": "web"   // "web" | "ios" | "android"
}

// Response 201
{
  "project": {
    "id": "proj_xyz789",
    "snippetId": "sdk_xyz789abc",
    ...
  }
}
GET/api/projects/:id

Get a single project by ID.

DELETE/api/projects/:id

Delete a project and all associated data.

#Scanning

POST/api/scan

Trigger a scan for a project. Returns immediately — scan runs asynchronously.

json
// Request body
{
  "projectId": "proj_a1b2c3",
  "url": "https://example.com"  // optional override
}

// Response 202 Accepted
{
  "scanId": "scan_abc123",
  "status": "queued",
  "estimatedSeconds": 20
}
GET/api/scan/:scanId

Get scan status and results.

json
// Response 200 (completed)
{
  "scanId": "scan_abc123",
  "status": "completed",        // queued | running | completed | failed
  "completedAt": "2025-02-01T14:31:15Z",
  "complianceScore": 72,
  "sdks": [
    {
      "name": "Google Analytics 4",
      "category": "analytics",
      "riskLevel": "medium",
      "detectedAt": "https://example.com/",
      "gdprRelevant": true
    },
    {
      "name": "Meta Pixel",
      "category": "advertising",
      "riskLevel": "high",
      "detectedAt": "https://example.com/",
      "gdprRelevant": true
    }
  ],
  "recommendations": [
    "Add consent gate for Meta Pixel (advertising category)",
    "Defer Google Analytics load until analytics consent is given"
  ]
}
POST/api/consent

Record a consent decision (called automatically by the banner).

json
// Request body
{
  "snippetId": "sdk_a1b2c3d4e5f6",
  "consentId": "user-uuid-generated-client-side",
  "decisions": {
    "analytics": true,
    "advertising": false,
    "functional": true,
    "preferences": true
  },
  "userAgent": "Mozilla/5.0 ...",
  "lang": "en"
}

// Response 201
{
  "consentId": "cns_xyz",
  "recordedAt": "2025-02-01T14:30:00Z"
}
GET/api/consent/:consentId

Look up a specific consent record by ID.

json
// Response 200
{
  "consentId": "cns_xyz",
  "snippetId": "sdk_a1b2c3d4e5f6",
  "decisions": { "analytics": true, "advertising": false, ... },
  "createdAt": "2025-02-01T14:30:00Z",
  "updatedAt": "2025-02-01T14:30:00Z"
}

#Rate Limits

EndpointFreePro
POST /api/scan10 / month500 / month
GET /api/projects60 / min600 / min
POST /api/consent10,000 / dayUnlimited

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

#Error Codes

HTTPCodeDescription
400invalid_requestMissing or malformed parameters
401unauthorizedMissing or invalid API key
403forbiddenValid key but insufficient permissions
404not_foundResource does not exist
409conflictDuplicate resource (e.g. project name)
429rate_limitedRate limit exceeded
500internal_errorServer error — please retry
json
// Error response shape
{
  "error": {
    "code": "rate_limited",
    "message": "You have exceeded the scan limit for your plan.",
    "retryAfter": 1706784000
  }
}