Download OpenAPI specification:Download
Welcome to the HostedScan API documentation.
The best way to get acquainted with HostedScan is to head over to our website and start running scans. Try it out here!
This documentation covers the API and webhook integrations. Use the API to run scans, get results, and manage risks. Use webhook integrations to receive real-time event notifications in your application.
Any questions? Please email us at hello@hostedscan.com
HostedScan offers a comprehensive REST API at https://api.hostedscan.com/v1. The API enables you to create Targets, set up Scans for those targets, along with fetching the resulting Risks and Reports. Webhooks are available to notify your application about important events, like the completion of scans, or the discovery of new risks for specific targets.
The API also enables you to upload your own scan results from internal scanning.
Authenticate by setting the X-HOSTEDSCAN-API-KEY
request header as your API key. You can create an API key by visiting the API & Webhooks section of your account settings.
To try out the APIs with sample data, use the api key test-data-key
. Requests made with this api key will return sample responses. For example:
curl -H "X-HOSTEDSCAN-API-KEY: test-data-key" --request GET https://api.hostedscan.com/v1/scans
There are Try it!
request samples throughout this documentation.
Status Code | Details |
---|---|
200 | OK - Successful request. |
400 | Bad Request - Invalid request parameters or missing required parameters. |
401 | Unauthorized - Invalid API key. |
404 | Not Found - No resource at the requested path. |
500 | Internal Server Error - Something went wrong on our server. |
The API is defined using the OpenAPI (Swagger) standard. Download our OpenAPI file at the top of this page to get started.
There are tools to generate clients in most programming languages from OpenAPI definitions. The easiest way to get started is with the online swagger.io editor, which has many built-in client generators or check out this comprehensive list of client generators.
Many API tools, such as Postman, also support importing OpenAPI definitions.
You can import our OpenAPI document into Postman to quickly and easily test our API. Download our OpenAPI file at the top of this page to get started.
Generally, when a field or webhook event is deprecated, the field or webhook event is still preserved in the API to prevent unnecessary customer rework. As such you may see some additional fields in a response or webhook events that are not documented in these API documents. Our recommendation is to ignore these.
Run scanners such as OpenVas, Nmap, and ZAP against your Targets. Creating a scan starts the scanner for the given target(s). Fetching a Scan object gives the results from the specific scanner.
New Scans are created in the QUEUED
state and will transition to RUNNING
while they are in progress and then to SUCCEEDED
when finished. To check if a Scan is finished, either periodically GET the Scan or integrate with the HostedScan webhooks and listen for the scan updated event.
The discovered vulnerabilities and output files are available once a scan has SUCCEEDED
. In the HostedScan API, the vulnerabilities are called Risks and there are management features, such as tracking Risks over time and accepting Risks that are false positives or by design.
On the Scan object, there is a property risks
, which breaks the Risks into 3 categories:
new_open
: Risks that were detected for the first time on the Target and Risks that had closed and now, re-openedstill_open
: Risks that were detected by a previous Scan of the Target and detected again by the current Scanclosed
: Risks that were detected by a previous Scan of the Target and not detected by the current ScanTo get all of the vulnerabilities found by the Scan, combine new_open
and still_open
. The Risks are given as an array of ids. Use the Risks api to get the full information for each id: GET https://api.hostedscan.com/v1/risks/{risk_id}
Use the scan result api to download the raw output files generated by the scanner software.
Use the reports api to programmatically generate the executive style PDF reports that are created in the HostedScan web application at https://hostedscan.com/reports.
Run a new vulnerability scan. Choose the Targets to scan by sending either the target values (e.g. https://example.com or 123.123.123.123), the ID of a Target already created in your HostedScan account, or using the tags feature and the Scan will automatically include all Targets with matching tags.
type | string (RunnableScanType) Enum: "NMAP" "NMAP_UDP" "OPENVAS" "OWASP_ZAP" "OWASP_ZAP_ACTIVE" "SSLYZE" |
targets | Array of strings Targets to scan. e.g. |
target_ids | Array of strings Ids of the targets to scan. Either tags, targets, or target_ids must be specified. |
tags | Array of strings Tags to scan. e.g. |
use_authentication | boolean Use authentication, if configured for the target(s). See Authenticated Web Application Vulnerability Scan for more details. |
required | object (Scan) The created Scan object |
{- "type": "NMAP",
- "targets": [
- "hostedscan.com"
], - "target_ids": [
- "36361122caac53b5e8c6616987"
], - "tags": [
- "prod"
], - "use_authentication": true
}
{- "data": {
- "id": "123422caac53b5e8c6616123",
- "type": "NMAP",
- "state": "RUNNING",
- "progress": 57,
- "risks": {
- "new_open": [
- {
- "risk_id": "5432122caac53b5e8c6616123"
}
], - "still_open": [
- {
- "risk_id": "13131122caac53b5e8c6616123"
}
], - "closed": [
- {
- "risk_id": "232321122caac53b5e8c6616123"
}
]
}, - "results": [
- {
- "result_id": "14141122caac53b5e8c6616123",
- "content_type": "application/json"
}
], - "requested_targets": [
- {
- "target_id": "36361122caac53b5e8c6616987",
- "target": "hostedscan.com"
}
], - "resolved_targets": [
], - "skipped_targets": [
- {
- "target_id": "17171122caac53b5e8c6616987",
- "skipped_reason": "OWASP ZAP scans websites. Unable to GET a website at the target. By default ZAP checks port 80 and 443. Scan an alternative port by setting it on the target url \"www.example.com:1234\""
}
]
}
}
Returns all Scans
page_token | string If there are more than 500 objects to return, the results will be truncated. Use page_token to request additional pages of results. |
filters | object Key value pairs of filters, where each value is an array to filter on. E.g. |
required | Array of objects (Scan) |
next_page_token | string Token that is present when there are more results than can fit in the response. Use the token to get the page of results. |
curl https://api.hostedscan.com/v1/scans \ -H 'X-HOSTEDSCAN-API-KEY: test-data-key'
{- "data": [
- {
- "id": "123422caac53b5e8c6616123",
- "type": "NMAP",
- "state": "RUNNING",
- "progress": 57,
- "risks": {
- "new_open": [
- {
- "risk_id": "5432122caac53b5e8c6616123"
}
], - "still_open": [
- {
- "risk_id": "13131122caac53b5e8c6616123"
}
], - "closed": [
- {
- "risk_id": "232321122caac53b5e8c6616123"
}
]
}, - "results": [
- {
- "result_id": "14141122caac53b5e8c6616123",
- "content_type": "application/json"
}
], - "requested_targets": [
- {
- "target_id": "36361122caac53b5e8c6616987",
- "target": "hostedscan.com"
}
], - "resolved_targets": [
], - "skipped_targets": [
- {
- "target_id": "17171122caac53b5e8c6616987",
- "skipped_reason": "OWASP ZAP scans websites. Unable to GET a website at the target. By default ZAP checks port 80 and 443. Scan an alternative port by setting it on the target url \"www.example.com:1234\""
}
]
}
], - "next_page_token": "string"
}
Returns a single Scan
id required | string ID of the Scan to get |
required | object (Scan) The Scan object |
curl https://api.hostedscan.com/v1/scans/10000000000000000000001 \ -H "X-HOSTEDSCAN-API-KEY: test-data-key"
{- "data": {
- "id": "123422caac53b5e8c6616123",
- "type": "NMAP",
- "state": "RUNNING",
- "progress": 57,
- "risks": {
- "new_open": [
- {
- "risk_id": "5432122caac53b5e8c6616123"
}
], - "still_open": [
- {
- "risk_id": "13131122caac53b5e8c6616123"
}
], - "closed": [
- {
- "risk_id": "232321122caac53b5e8c6616123"
}
]
}, - "results": [
- {
- "result_id": "14141122caac53b5e8c6616123",
- "content_type": "application/json"
}
], - "requested_targets": [
- {
- "target_id": "36361122caac53b5e8c6616987",
- "target": "hostedscan.com"
}
], - "resolved_targets": [
], - "skipped_targets": [
- {
- "target_id": "17171122caac53b5e8c6616987",
- "skipped_reason": "OWASP ZAP scans websites. Unable to GET a website at the target. By default ZAP checks port 80 and 443. Scan an alternative port by setting it on the target url \"www.example.com:1234\""
}
]
}
}
This section explains how to run an authenticated scan with the API. For general info on HostedScan's authenticated scanning features see https://hostedscan.com/authenticated-web-app-vulnerability-scan.
use_authentication: true
in the requestMake a POST request with content-type: multipart/form-data
and one file to the endpoint https://api.hostedscan.com/v1/targets/:target_id/auth/selenium
.
curl -H "X-HOSTEDSCAN-API-KEY: <<your api key>>" -F file=@YourSeleniumRecording.side https://api.hostedscan.com/v1/targets/your-target-id/auth/selenium
Risks are the vulnerability findings from scans. For example, a vulnerable javascript dependency or an open port.
Returns all Risks
page_token | string If there are more than 500 objects to return, the results will be truncated. Use page_token to request additional pages of results. |
filters | object Key value pairs of filters, where each value is an array to filter on. E.g. |
required | Array of objects (Risk) |
next_page_token | string Token that is present when there are more results than can fit in the response. Use the token to get the page of results. |
curl -H "X-HOSTEDSCAN-API-KEY: test-data-key" --request GET https://api.hostedscan.com/v1/risks
{- "data": [
- {
- "id": "111122caac53b5e8c6616123",
- "target_id": "211122caac53b5e8c6616321",
- "target_label": "production-website",
- "tags": [
- "prod"
], - "status": "OPEN",
- "first_detected_at": "2019-08-24T14:15:22Z",
- "last_detected_at": "2019-08-24T14:15:22Z",
- "is_accepted": true,
- "accepted_by": [
- {
- "note": "Expected behavior for production webserver to have ports 80 and 443 open",
- "created_at": "2019-08-24T14:15:22Z",
- "last_updated_at": "2019-08-24T14:15:22Z"
}
], - "risk_definition": {
- "scan_type": "NMAP",
- "title": "Port 443 Open",
- "threat_level": "MEDIUM",
- "description": "Port 443 was detected open.",
- "solution": "",
- "cvss": "",
- "additional_info": { }
}
}
], - "next_page_token": "string"
}
Returns a single Risk
id required | string ID of the Risk to get |
required | object (Risk) The Risk object |
curl -H "X-HOSTEDSCAN-API-KEY: test-data-key" --request GET https://api.hostedscan.com/v1/risks/12345
{- "data": {
- "id": "111122caac53b5e8c6616123",
- "target_id": "211122caac53b5e8c6616321",
- "target_label": "production-website",
- "tags": [
- "prod"
], - "status": "OPEN",
- "first_detected_at": "2019-08-24T14:15:22Z",
- "last_detected_at": "2019-08-24T14:15:22Z",
- "is_accepted": true,
- "accepted_by": [
- {
- "note": "Expected behavior for production webserver to have ports 80 and 443 open",
- "created_at": "2019-08-24T14:15:22Z",
- "last_updated_at": "2019-08-24T14:15:22Z"
}
], - "risk_definition": {
- "scan_type": "NMAP",
- "title": "Port 443 Open",
- "threat_level": "MEDIUM",
- "description": "Port 443 was detected open.",
- "solution": "",
- "cvss": "",
- "additional_info": { }
}
}
}
Targets are the servers and websites to be scanned for vulnerabilities. A target is defined by an IP address, URL, or Fully Qualified Domain Name.
Create a new Target
upsert | boolean Update target if it already exists. Defaults to false. |
target required | string IPv4, URL, or Fully Qualified Domain Name, eg. |
label | string Label for the Target |
tags | Array of strings Up to 10 tags for filtering, selecting, and sorting |
object (ScannerSettings) The settings to use with a particular scanner when scanning this target. |
required | object (Target) The created Target object |
{- "target": "hostedscan.com",
- "label": "production website",
- "tags": [
- "prod"
], - "scanner_settings": {
- "zap": {
- "included_domains": [
- "app.example.com"
], - "excluded_domains": [
- "blog.example.com"
], - "scan_discovered_subdomains": true,
- "scan_third_party_javascript": true,
- "headers": [
- {
- "key": "X-API-KEY",
- "value": "example"
}
], - "cookies": [
- {
- "domain": "example.com",
- "expiry": 1734732496,
- "name": "mycookie",
- "path": "/webapp",
- "sameSite": "Strict",
- "secure": true,
- "value": "test123"
}
]
}
}
}
{- "data": {
- "id": "111122caac53b5e8c6616e12",
- "target": "www.example.com",
- "label": "production-website",
- "tags": [
- "prod"
], - "source_type": "MANUAL"
}
}
Returns all Targets
page_token | string If there are more than 500 objects to return, the results will be truncated. Use page_token to request additional pages of results. |
object Key value pairs of filters, where each value is an array to filter on. E.g. |
required | Array of objects (Target) |
next_page_token | string Token that is present when there are more results than can fit in the response. Use the token to get the page of results. |
curl --request GET https://api.hostedscan.com/v1/targets \ -H "X-HOSTEDSCAN-API-KEY: test-data-key"
{- "data": [
- {
- "id": "111122caac53b5e8c6616e12",
- "target": "www.example.com",
- "label": "production-website",
- "tags": [
- "prod"
], - "source_type": "MANUAL"
}
], - "next_page_token": "string"
}
Returns a single Target
id required | string ID of the Target to get |
required | object (Target) The Target object |
curl -H "X-HOSTEDSCAN-API-KEY: test-data-key" --request GET https://api.hostedscan.com/v1/targets/12345
{- "data": {
- "id": "111122caac53b5e8c6616e12",
- "target": "www.example.com",
- "label": "production-website",
- "tags": [
- "prod"
], - "source_type": "MANUAL"
}
}
Update a Target
id required | string ID of the Target to update |
label | string Label for the Target |
tags | Array of strings Up to 10 tags for filtering, selecting, and sorting |
object (ScannerSettings) The settings to use with a particular scanner when scanning this target. |
required | object (Target) The updated Target object |
{- "label": "production-webserver",
- "tags": [
- "prod"
], - "scanner_settings": {
- "zap": {
- "included_domains": [
- "app.example.com"
], - "excluded_domains": [
- "blog.example.com"
], - "scan_discovered_subdomains": true,
- "scan_third_party_javascript": true,
- "headers": [
- {
- "key": "X-API-KEY",
- "value": "example"
}
], - "cookies": [
- {
- "domain": "example.com",
- "expiry": 1734732496,
- "name": "mycookie",
- "path": "/webapp",
- "sameSite": "Strict",
- "secure": true,
- "value": "test123"
}
]
}
}
}
{- "data": {
- "id": "111122caac53b5e8c6616e12",
- "target": "www.example.com",
- "label": "production-website",
- "tags": [
- "prod"
], - "source_type": "MANUAL"
}
}
Delete a Target by id
Note: Deleting a target will also delete any risks associated with that target.
id required | string ID of the Target to delete |
curl -H "X-HOSTEDSCAN-API-KEY: test-data-key" --request DELETE https://api.hostedscan.com/v1/targets/12345
Create a new Report
report_format required | string Enum: "PDF" "HTML"
|
targets_filter | object Array of target ids or tags. |
risks_filter | object Key value pairs of filters, where each value is an array to filter on. E.g.
|
{- "report_format": "PDF",
- "targets_filter": { },
- "risks_filter": { }
}
Download a Report
id required | string ID of the Report to get |
curl --header "X-HOSTEDSCAN-API-KEY: your-api-key-here" \ --request GET \ --output report.pdf \ https://api.hostedscan.com/v1/reports/id-of-created-report-here
HostedScan supports uploading results from your own installations of Nmap, OpenVAS, and ZAP. To do so, first create a Source, which is a group of related targets and scans. Then, upload the result files from your scans to the new Source. For more detailed instructions and examples see https://hostedscan.com/internal-vulnerability-scanning.
Create a new Source
source_type required | string Value: "IMPORTED" |
name required | string A name for the Source |
required | object |
{- "source_type": "IMPORTED",
- "name": "HQ Internal Network"
}
{- "data": {
- "id": "39391122caac7655e8c6616987",
- "source_type": "IMPORTED",
- "name": "HQ Internal Network"
}
}
Upload a Scan Result
source_id required | string Id of the Source that this result will be grouped with |
scan_type required | string (ScanType) Enum: "DEPENDABOT" "NMAP" "NMAP_UDP" "OPENVAS" "OWASP_ZAP" "OWASP_ZAP_ACTIVE" "SSLYZE" |
target | string The target that was scanned. e.g. https://example.com. Required only for the |
HostedScan uses webhooks to send event notifications to your application. Receive events when scans finish or when new risks are discovered.
The webhook notifications sent by HostedScan are Event objects. An Event is a JSON structure with the following properties: the event id
, the event_created_at
time, the event type
, and the data
. The data
is specific for each event. E.g. for a risk.created
event the data is the Risk object and for a scan.created
event the data is the Scan object.
{
"id": "12345",
"event_created_at": "2023-08-11T05:52:56.104Z",
"type": "risk.created",
"data": {
...
}
}
Your webhook endpoint must use HTTPS with a signed certificate, such as one from https://letsencrypt.org/. HostedScan will not send to endpoints using self-signed certificates.
You can register new webhook endpoints and view your existing webhook endpoints in your account settings at https://hostedscan.com/settings.
Any 2xx response code from your endpoint is treated as a successful delivery. Any non-2xx status code (or a timeout) is treated as a failure and will be retried. HostedScan will attempt to deliver messages to your endpoint for up to 12 hours, with exponential backoff.
When you register an endpoint, HostedScan creates a signing secret for that endpoint. HostedScan uses this secret to send a signature in the header of each Event message. The signature can be validated using the signing secret to verify that an event was sent by HostedScan.
Each webhook message request includes an http header X-HOSTEDSCAN-SIGNATURE
. The X-HOSTEDSCAN-SIGNATURE
is a hash-based message authentication code (HMAC) generated with SHA-256. To validate this signature an application will first recreate the signature using the signing secret for that endpoint and then check that the signature sent in the X-HOSTEDSCAN-SIGNATURE
header matches the recreated signature. To do this, follow the steps below:
X-HOSTEDSCAN-TIMESTAMP
header), the character . , and the JSON payload sent in the request body.X-HOSTEDSCAN-SIGNATURE
header.The hostedscan-api-examples Github repository has sample code for receiving webhooks with an AWS Lambda function.
The API has deprecated a couple of events you will see at your webhook endpoint. Our policy is to generally preserve API behavior to prevent unnecessary rework. The following events have been deprecated:
scan.succeeded
risk.opened
risk.closed
Our recommendation is to ignore these. Instead, the API uses created
and updated
events to denote changes to scans and risks.
A new Scan has been created
id required | string |
event_created_at | string <date-time> |
type required | string Value: "scan.created" |
required | object |
{- "id": "string",
- "event_created_at": "2019-08-24T14:15:22Z",
- "type": "scan.created",
- "data": {
- "id": "123422caac53b5e8c6616123",
- "type": "NMAP",
- "state": "RUNNING",
- "progress": 57,
- "risks": {
- "new_open": [
- {
- "risk_id": "5432122caac53b5e8c6616123"
}
], - "still_open": [
- {
- "risk_id": "13131122caac53b5e8c6616123"
}
], - "closed": [
- {
- "risk_id": "232321122caac53b5e8c6616123"
}
]
}, - "results": [
- {
- "result_id": "14141122caac53b5e8c6616123",
- "content_type": "application/json"
}
], - "requested_targets": [
- {
- "target_id": "36361122caac53b5e8c6616987",
- "target": "hostedscan.com"
}
], - "resolved_targets": [
], - "skipped_targets": [
- {
- "target_id": "17171122caac53b5e8c6616987",
- "skipped_reason": "OWASP ZAP scans websites. Unable to GET a website at the target. By default ZAP checks port 80 and 443. Scan an alternative port by setting it on the target url \"www.example.com:1234\""
}
]
}
}
A Scan has been updated
id required | string |
event_created_at | string <date-time> |
type required | string Value: "scan.updated" |
required | object |
{- "id": "string",
- "event_created_at": "2019-08-24T14:15:22Z",
- "type": "scan.updated",
- "data": {
- "id": "123422caac53b5e8c6616123",
- "type": "NMAP",
- "state": "RUNNING",
- "progress": 57,
- "risks": {
- "new_open": [
- {
- "risk_id": "5432122caac53b5e8c6616123"
}
], - "still_open": [
- {
- "risk_id": "13131122caac53b5e8c6616123"
}
], - "closed": [
- {
- "risk_id": "232321122caac53b5e8c6616123"
}
]
}, - "results": [
- {
- "result_id": "14141122caac53b5e8c6616123",
- "content_type": "application/json"
}
], - "requested_targets": [
- {
- "target_id": "36361122caac53b5e8c6616987",
- "target": "hostedscan.com"
}
], - "resolved_targets": [
], - "skipped_targets": [
- {
- "target_id": "17171122caac53b5e8c6616987",
- "skipped_reason": "OWASP ZAP scans websites. Unable to GET a website at the target. By default ZAP checks port 80 and 443. Scan an alternative port by setting it on the target url \"www.example.com:1234\""
}
]
}
}
A new Risk has been created
id required | string |
event_created_at | string <date-time> |
type required | string Value: "risk.created" |
required | object |
{- "id": "string",
- "event_created_at": "2019-08-24T14:15:22Z",
- "type": "risk.created",
- "data": {
- "id": "111122caac53b5e8c6616123",
- "target_id": "211122caac53b5e8c6616321",
- "target_label": "production-website",
- "tags": [
- "prod"
], - "status": "OPEN",
- "first_detected_at": "2019-08-24T14:15:22Z",
- "last_detected_at": "2019-08-24T14:15:22Z",
- "is_accepted": true,
- "accepted_by": [
- {
- "note": "Expected behavior for production webserver to have ports 80 and 443 open",
- "created_at": "2019-08-24T14:15:22Z",
- "last_updated_at": "2019-08-24T14:15:22Z"
}
], - "risk_definition": {
- "scan_type": "NMAP",
- "title": "Port 443 Open",
- "threat_level": "MEDIUM",
- "description": "Port 443 was detected open.",
- "solution": "",
- "cvss": "",
- "additional_info": { }
}
}
}
A Risk has been updated
id required | string |
event_created_at | string <date-time> |
type required | string Value: "risk.updated" |
required | object |
{- "id": "string",
- "event_created_at": "2019-08-24T14:15:22Z",
- "type": "risk.updated",
- "data": {
- "id": "111122caac53b5e8c6616123",
- "target_id": "211122caac53b5e8c6616321",
- "target_label": "production-website",
- "tags": [
- "prod"
], - "status": "OPEN",
- "first_detected_at": "2019-08-24T14:15:22Z",
- "last_detected_at": "2019-08-24T14:15:22Z",
- "is_accepted": true,
- "accepted_by": [
- {
- "note": "Expected behavior for production webserver to have ports 80 and 443 open",
- "created_at": "2019-08-24T14:15:22Z",
- "last_updated_at": "2019-08-24T14:15:22Z"
}
], - "risk_definition": {
- "scan_type": "NMAP",
- "title": "Port 443 Open",
- "threat_level": "MEDIUM",
- "description": "Port 443 was detected open.",
- "solution": "",
- "cvss": "",
- "additional_info": { }
}
}
}
Sample code can be found on Github at https://github.com/hostedscan/hostedscan-api-examples