API Reference

Complete endpoint reference for the StackShield REST API v1. All endpoints require authentication via the Authorization: Bearer header.

Checks

Checks represent monitored domains. Each check defines a domain, a scan schedule, and which security tests to run.

List Checks

GET /api/v1/checks

Query Parameters

ParameterTypeDescription
statusstringactive or inactive. Filters by check status.
searchstringSearch domains by partial match.
sortstringSort field: domain, created_at, last_run_at. Default: created_at.
directionstringasc or desc. Default: desc.
pageintegerPage number for pagination.

Response

{
  "data": [
    {
      "id": "9e5f1a2b-...",
      "domain": "example.com",
      "url": null,
      "is_active": true,
      "schedule_frequency": "DAILY",
      "schedule_time": "02:00",
      "tests": {
        "ssl_certificate": true,
        "security_headers": true,
        "csrf_protection": false
      },
      "is_verified": true,
      "last_run_at": "2026-03-07T02:00:00+00:00",
      "next_run_at": "2026-03-08T02:00:00+00:00",
      "created_at": "2026-02-15T10:30:00+00:00",
      "latest_scan": {
        "id": "a1b2c3d4-...",
        "status": "completed",
        "pass_rate": 91.67,
        ...
      }
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Create Check

POST /api/v1/checks

Request Body

FieldTypeRequiredDescription
domainstringYesDomain or URL to monitor. If a full URL is provided the domain is extracted automatically.
schedule_frequencystringYesHOURLY, DAILY, WEEKLY, or MONTHLY.
schedule_timestringConditionalTime in HH:MM format. Required unless frequency is HOURLY.
testsobjectYesMap of test keys to booleans, e.g. {"ssl_certificate": true, "csrf_protection": false}.
test_configsobjectNoCustom configuration for tests that support it (e.g. brute_force, api_rate_limit, cors_misconfiguration). Each key maps to a settings object with an endpoints array.

Example

curl -X POST -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "schedule_frequency": "DAILY",
    "schedule_time": "03:00",
    "tests": {
      "ssl_certificate": true,
      "security_headers": true,
      "csrf_protection": true,
      "brute_force": true
    },
    "test_configs": {
      "brute_force": {
        "endpoints": ["/login", "/admin/login"]
      }
    }
  }' \
  https://stackshield.io/api/v1/checks

Returns 201 Created with the check resource.

Get Check

GET /api/v1/checks/{check_id}

Returns a single check with its latest scan and schedule information.

Update Check

PUT /api/v1/checks/{check_id}

All fields are optional. Only include the fields you want to change.

Request Body

FieldTypeDescription
domainstringNew domain or URL.
is_activebooleanEnable or disable the check.
schedule_frequencystringHOURLY, DAILY, WEEKLY, or MONTHLY.
schedule_timestringTime in HH:MM format.
testsobjectMap of test keys to booleans.
test_configsobjectCustom test configurations.

Example — disable a check

curl -X PUT -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}' \
  https://stackshield.io/api/v1/checks/{check_id}

Delete Check

DELETE /api/v1/checks/{check_id}

Soft-deletes the check and its test configurations. Returns 204 No Content.

curl -X DELETE -H "Authorization: Bearer $API_KEY" \
  https://stackshield.io/api/v1/checks/{check_id}

Scans

A scan is a single execution of all enabled security tests against a check's domain.

List Scans

GET /api/v1/scans

Query Parameters

ParameterTypeDescription
check_idstringFilter scans by check ID.
statusstringFilter by scan status (e.g. pending, in_progress, completed, failed).
has_critical_issuesbooleanFilter to scans with or without critical issues.
pageintegerPage number.

Response

{
  "data": [
    {
      "id": "a1b2c3d4-...",
      "check_id": "9e5f1a2b-...",
      "status": "completed",
      "started_at": "2026-03-07T02:00:05+00:00",
      "completed_at": "2026-03-07T02:01:42+00:00",
      "total_tests": 12,
      "passed_tests": 11,
      "failed_tests": 1,
      "warning_tests": 0,
      "has_critical_issues": false,
      "triggered_by": "system",
      "pass_rate": 91.67,
      "created_at": "2026-03-07T02:00:00+00:00",
      "check": {
        "id": "9e5f1a2b-...",
        "domain": "example.com"
      }
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Get Scan

GET /api/v1/scans/{scan_id}

Returns the scan with its check and all scan test results included.

Trigger Scan

POST /api/v1/checks/{check_id}/scans

Triggers a new security scan for the specified check. The check must be active.

Returns 201 Created with the new scan resource. The scan runs asynchronously — poll the Get Scan endpoint to monitor progress.

curl -X POST -H "Authorization: Bearer $API_KEY" \
  https://stackshield.io/api/v1/checks/{check_id}/scans

Scan Tests

Each scan is composed of individual tests (SSL check, header analysis, CSRF verification, etc.). These endpoints let you inspect per-test results.

List Scan Tests

GET /api/v1/scans/{scan_id}/tests

Query Parameters

ParameterTypeDescription
statusstringFilter by test status: passed, failed, warning, pending, running.
pageintegerPage number.

Response

{
  "data": [
    {
      "id": "f1e2d3c4-...",
      "scan_id": "a1b2c3d4-...",
      "test_type": "ssl_certificate",
      "status": "passed",
      "message": "SSL certificate is valid and properly configured.",
      "started_at": "2026-03-07T02:00:05+00:00",
      "completed_at": "2026-03-07T02:00:08+00:00"
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Get Scan Test

GET /api/v1/scans/{scan_id}/tests/{test_id}

Returns a single test result with full detail including findings, remediation steps, and technical details.

Response

{
  "data": {
    "id": "f1e2d3c4-...",
    "scan_id": "a1b2c3d4-...",
    "test_type": "security_headers",
    "status": "failed",
    "message": "Missing critical security headers.",
    "started_at": "2026-03-07T02:00:10+00:00",
    "completed_at": "2026-03-07T02:00:12+00:00",
    "findings": [
      {
        "severity": "high",
        "title": "Missing Content-Security-Policy header",
        "description": "The Content-Security-Policy header is not set..."
      }
    ],
    "remediation_steps": [
      "Add the Content-Security-Policy header to your web server configuration.",
      "Use a strict policy that only allows resources from trusted sources."
    ],
    "technical_details": {
      "headers_checked": ["Content-Security-Policy", "X-Frame-Options", "..."],
      "missing_headers": ["Content-Security-Policy"]
    }
  }
}

Issues

Issues are persistent security findings tracked across scans. They are automatically created when a test detects a vulnerability and are deduplicated by fingerprint.

List Issues

GET /api/v1/issues

Query Parameters

ParameterTypeDescription
severitystringcritical, high, medium, or low.
statusstringresolved, unresolved, or all (default: all).
check_idstringFilter issues by check ID.
test_typestringFilter by test type key (e.g. ssl_certificate).
searchstringSearch in issue title and description.
pageintegerPage number.

Response

{
  "data": [
    {
      "id": "b5a4c3d2-...",
      "check_id": "9e5f1a2b-...",
      "test_type": "security_headers",
      "severity": "high",
      "title": "Missing Content-Security-Policy header",
      "description": "The Content-Security-Policy header is not configured...",
      "fingerprint": "sha256:...",
      "first_detected_at": "2026-02-20T14:30:00+00:00",
      "last_detected_at": "2026-03-07T02:01:00+00:00",
      "is_resolved": false,
      "resolved_at": null,
      "metadata": {},
      "created_at": "2026-02-20T14:30:00+00:00",
      "check": {
        "id": "9e5f1a2b-...",
        "domain": "example.com"
      }
    }
  ],
  "links": { ... },
  "meta": { ... }
}

Get Issue

GET /api/v1/issues/{issue_id}

Returns the full issue with its check and the last 10 related scans (since the issue was first detected).

Response

{
  "id": "b5a4c3d2-...",
  "check_id": "9e5f1a2b-...",
  "test_type": "security_headers",
  "severity": "high",
  "title": "Missing Content-Security-Policy header",
  "description": "...",
  "fingerprint": "sha256:...",
  "first_detected_at": "2026-02-20T14:30:00+00:00",
  "last_detected_at": "2026-03-07T02:01:00+00:00",
  "is_resolved": false,
  "resolved_at": null,
  "metadata": {},
  "created_at": "2026-02-20T14:30:00+00:00",
  "check": {
    "id": "9e5f1a2b-...",
    "domain": "example.com"
  },
  "related_scans": [
    {
      "id": "a1b2c3d4-...",
      "status": "completed",
      "created_at": "2026-03-07T02:00:00+00:00",
      "completed_at": "2026-03-07T02:01:42+00:00"
    }
  ]
}

Update Issue

PATCH /api/v1/issues/{issue_id}

Resolve or unresolve an issue.

Request Body

FieldTypeRequiredDescription
is_resolvedbooleanYestrue to resolve, false to unresolve.
resolution_notesstringNoOptional notes (max 1000 chars). Stored in issue metadata.

Example

curl -X PATCH -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "is_resolved": true,
    "resolution_notes": "Fixed in deploy v2.4.1"
  }' \
  https://stackshield.io/api/v1/issues/{issue_id}

Bulk Update Issues

POST /api/v1/issues/bulk

Resolve or unresolve multiple issues at once. Only issues belonging to your team are affected.

Request Body

FieldTypeRequiredDescription
issue_idsarrayYesArray of issue UUIDs (min: 1).
actionstringYesresolve or unresolve.

Example

curl -X POST -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "issue_ids": ["b5a4c3d2-...", "c6d7e8f9-..."],
    "action": "resolve"
  }' \
  https://stackshield.io/api/v1/issues/bulk

Response

{
  "message": "2 issues updated.",
  "count": 2
}

Export Issues

GET /api/v1/issues/export

Downloads all issues as a CSV file. The response streams with Content-Type: text/csv.

CSV Columns

Domain, Test Type, Severity, Title, Description, First Detected, Last Detected, Status, Resolved At

curl -H "Authorization: Bearer $API_KEY" \
  -o issues.csv \
  https://stackshield.io/api/v1/issues/export

Dashboard Stats

Retrieve aggregated dashboard statistics for your team. Results are cached for 5 minutes.

Get Stats

GET /api/v1/stats

Response

{
  "data": {
    "total_domains": 5,
    "active_scans": 1,
    "priority_issues": 3,
    "domains_at_risk": 2
  }
}
FieldDescription
total_domainsTotal number of checks (monitored domains) for the team.
active_scansNumber of scans currently in progress.
priority_issuesCount of critical and high severity findings from the latest scan of each domain.
domains_at_riskNumber of unique domains with at least one priority issue.