Documentation API REST API

REST API

Authentication, endpoints, objects and errors. With copy-paste examples that run.

The HAS API gives your team programmatic access to your company's vulnerabilities, pentests and dashboard. Use it to push findings into your SIEM, open tickets in your backlog, or close the remediation loop from your own workflow.

https://api.hackersec.com/v1
The OpenAPI 3.2 specification lives at api.hackersec.com/v1/openapi.json. Import it into Postman or Insomnia to get every endpoint ready, or use it to generate a client in your language.

Authentication

Every request carries your secret key in the Authorization header:

curl https://api.hackersec.com/v1/dashboard \
  -H "Authorization: Bearer hackersec_has_sk_..."

Creating a key

Scopes

ScopeCan
readQuery vulnerabilities, pentests and the dashboard.
read_writeEverything read can, plus change status, request retests and trigger integrations.

Scope is chosen at creation and holds for the life of the key. For an integration that only queries, such as a dashboard, SIEM or report, use read.

Treat the key as a password. Store it in your team's secret manager, use it only in code that runs on a server, and rotate periodically by creating the new key before revoking the old one.

Conventions

Lists and pagination

Every listing returns the same envelope, newest first:

{
  "object": "list",
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "5214"
}

Use limit (default 100, max 200) and pass next_cursor as starting_after for the next page. While has_more is true, there is more to fetch.

Endpoints

MethodPathWhat it does
GET/v1/dashboardCounts by severity and status, plus a pentest summary
GET/v1/vulnerabilitiesList, with filters
GET/v1/vulnerabilities/{id}One vulnerability, with evidence and comments
GET/v1/testsList of pentests
GET/v1/tests/{id}One pentest, with scope
POST/v1/vulnerabilities/{id}/statusChange status
POST/v1/vulnerabilities/{id}/retestRequest a retest
POST/v1/vulnerabilities/{id}/exportSend to the configured integration

List vulnerabilities

Filters: severity, status, test, limit, starting_after. The values for severity and status are the same ones the response returns.

curl "https://api.hackersec.com/v1/vulnerabilities?severity=critical&status=reported" \
  -H "Authorization: Bearer $HACKERSEC_KEY"

Change status

Accepted values: reported, in_correction, ignored, mitigated, retest.

curl -X POST https://api.hackersec.com/v1/vulnerabilities/16590818124833/status \
  -H "Authorization: Bearer $HACKERSEC_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"in_correction"}'

ignored and mitigated require justification, 50 to 2800 characters. These are your own declarations: one accepts the risk as is, the other states a compensating control exists. The text appears in the PDF report next to the vulnerability, so write the real decision.

curl -X POST https://api.hackersec.com/v1/vulnerabilities/16590818124833/status \
  -H "Authorization: Bearer $HACKERSEC_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"ignored","justification":"Endpoint reachable only through the corporate VPN with mandatory MFA. Risk accepted by the security committee on Aug 12."}'

Request a retest

curl -X POST https://api.hackersec.com/v1/vulnerabilities/16590818124833/retest \
  -H "Authorization: Bearer $HACKERSEC_KEY" \
  -H "Content-Type: application/json" \
  -d '{"context":"Parameter now uses a parameterized query. Deployed to production today."}'

context is optional and helps: it tells whoever retests what changed. With a retest already pending for that vulnerability, the call returns 409, signalling that the previous request is still running.

Send to the integration

curl -X POST https://api.hackersec.com/v1/vulnerabilities/16590818124833/export \
  -H "Authorization: Bearer $HACKERSEC_KEY" \
  -H "Content-Type: application/json" \
  -d '{"integration":"jira"}'

Omit integration or use "all" to fire every active integration. Requires an integration configured for the company and a master's key.

The Vulnerability object

FieldDescription
idThe same identifier shown in the platform
nameTechnical type and short impact
targetThe exact asset where the flaw was confirmed
severityinfo, low, medium, high, critical
statusreported, in_correction, fixed, ignored, retest, not_fixed, mitigated
cvss_score, cvss_vectorCVSS 4.0
financial_impactEstimated financial impact
testid of the pentest it was found in
reported_at, fixed_atDates

Fetching a single vulnerability also returns description, remediation, references, evidence (the proofs of concept) and comments.

The Test object

FieldDescription
id, namePentest identifier and name
levelai_native or ai_first
statusrequested, in_progress, paused, retest, completed
assetsAssets in scope
vulnerabilitiesCounts by severity
created_at, started_at, ended_atDates

Errors

{
  "error": {
    "type": "invalid_request_error",
    "code": "justification_required",
    "message": "A justification of at least 50 characters is required...",
    "param": "justification"
  },
  "request_id": "req_28d675e64f3fe329"
}
HTTPWhen
400Invalid JSON, unknown field or out-of-range value. The param field says which.
401Key missing, invalid or revoked.
403A read key on a write operation, or an expired contract.
404The resource is out of reach for this key.
409The operation conflicts with the current state. Example: a retest already pending.