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
/api/v1/checks
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | active or inactive. Filters by check status. |
search | string | Search domains by partial match. |
sort | string | Sort field: domain, created_at, last_run_at. Default: created_at. |
direction | string | asc or desc. Default: desc. |
page | integer | Page 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
/api/v1/checks
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | Domain or URL to monitor. If a full URL is provided the domain is extracted automatically. |
schedule_frequency | string | Yes | HOURLY, DAILY, WEEKLY, or MONTHLY. |
schedule_time | string | Conditional | Time in HH:MM format. Required unless frequency is HOURLY. |
tests | object | Yes | Map of test keys to booleans, e.g. {"ssl_certificate": true, "csrf_protection": false}. |
test_configs | object | No | Custom 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
/api/v1/checks/{check_id}
Returns a single check with its latest scan and schedule information.
Update Check
/api/v1/checks/{check_id}
All fields are optional. Only include the fields you want to change.
Request Body
| Field | Type | Description |
|---|---|---|
domain | string | New domain or URL. |
is_active | boolean | Enable or disable the check. |
schedule_frequency | string | HOURLY, DAILY, WEEKLY, or MONTHLY. |
schedule_time | string | Time in HH:MM format. |
tests | object | Map of test keys to booleans. |
test_configs | object | Custom 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
/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
/api/v1/scans
Query Parameters
| Parameter | Type | Description |
|---|---|---|
check_id | string | Filter scans by check ID. |
status | string | Filter by scan status (e.g. pending, in_progress, completed, failed). |
has_critical_issues | boolean | Filter to scans with or without critical issues. |
page | integer | Page 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
/api/v1/scans/{scan_id}
Returns the scan with its check and all scan test results included.
Trigger Scan
/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
/api/v1/scans/{scan_id}/tests
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by test status: passed, failed, warning, pending, running. |
page | integer | Page 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
/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
/api/v1/issues
Query Parameters
| Parameter | Type | Description |
|---|---|---|
severity | string | critical, high, medium, or low. |
status | string | resolved, unresolved, or all (default: all). |
check_id | string | Filter issues by check ID. |
test_type | string | Filter by test type key (e.g. ssl_certificate). |
search | string | Search in issue title and description. |
page | integer | Page 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
/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
/api/v1/issues/{issue_id}
Resolve or unresolve an issue.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
is_resolved | boolean | Yes | true to resolve, false to unresolve. |
resolution_notes | string | No | Optional 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
/api/v1/issues/bulk
Resolve or unresolve multiple issues at once. Only issues belonging to your team are affected.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
issue_ids | array | Yes | Array of issue UUIDs (min: 1). |
action | string | Yes | resolve 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
/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
/api/v1/stats
Response
{
"data": {
"total_domains": 5,
"active_scans": 1,
"priority_issues": 3,
"domains_at_risk": 2
}
}
| Field | Description |
|---|---|
total_domains | Total number of checks (monitored domains) for the team. |
active_scans | Number of scans currently in progress. |
priority_issues | Count of critical and high severity findings from the latest scan of each domain. |
domains_at_risk | Number of unique domains with at least one priority issue. |