The VulnCheck API makes it easy to get started with VulnCheck Target Intelligence. To start, simply query the target-intel index via the /v3/index/:index?cve=:cve API as follows:
curl --request GET \
--url https://api.vulncheck.com/v3/index/target-intel?cve=CVE-2024-21887 \
--header 'Accept: application/json' \
--header 'Authorization: Bearer insert_token_here'
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"os"
vulncheck "github.com/vulncheck-oss/sdk-go-v2/v2"
)
func main() {
configuration := vulncheck.NewConfiguration()
configuration.Scheme = "https"
configuration.Host = "api.vulncheck.com"
client := vulncheck.NewAPIClient(configuration)
token := os.Getenv("VULNCHECK_API_TOKEN")
auth := context.WithValue(
context.Background(),
vulncheck.ContextAPIKeys,
map[string]vulncheck.APIKey{
"Bearer": {Key: token},
},
)
resp, httpRes, err := client.IndicesAPI.IndexTargetIntelGet(auth).Cve("CVE-2024-21887").Execute()
if err != nil || httpRes.StatusCode != 200 {
log.Fatal(err)
}
prettyJSON, err := json.MarshalIndent(resp.Data, "", " ")
if err != nil {
log.Fatalf("Failed to generate JSON: %v", err)
return
}
fmt.Println(string(prettyJSON))
}
import vulncheck_sdk
configuration = vulncheck_sdk.Configuration(host="https://api.vulncheck.com/v3")
configuration.api_key["Bearer"] = "insert_token_here"
with vulncheck_sdk.ApiClient(configuration) as api_client:
indices_client = vulncheck_sdk.IndicesApi(api_client)
api_response = indices_client.index_target_intel_get(cve="CVE-2024-21887")
print(api_response.data)
vulncheck index browse target-intel --cve CVE-2024-21887
The above example searches the target-intel index for every host confirmed to be running software affected by CVE-2024-21887.
Each result represents a single observed host-port-service tuple — one IP, one port, and the service identified on it. A host with several exposed services appears as several records.
After calling the /v3/index/target-intel?cve=:cve API endpoint with a valid CVE identifier, a response similar to the below will be returned:
{
"_benchmark": 0.050314,
"_meta": {
"timestamp": "2026-09-14T18:22:27.132288937Z",
"index": "target-intel",
"limit": 100,
"total_documents": 411,
"sort": "_timestamp",
"order": "desc",
"page": 1,
"total_pages": 5,
// ...
},
"data": [
{
"ip": "203.0.113.42",
"hostname": "vpn.test.com",
"port": 443,
"timestamp": "2026-09-13T22:12:36.749Z",
"date_added": "2026-06-11T11:22:30.592Z",
"protocol": "http",
"transport": "tcp",
"cpe": [
"cpe:2.3:a:ivanti:connect_secure:9.1:r15.2:*:*:*:*:*:*"
],
"cve": [
"CVE-2023-46805",
"CVE-2024-21887",
"CVE-2024-21893"
],
"cve_confirmed": [
{ "cve_id": "CVE-2023-46805", "confirmed": true },
{ "cve_id": "CVE-2024-21887", "confirmed": true },
{ "cve_id": "CVE-2024-21893", "confirmed": true }
],
"vendor": ["ivanti"],
"product": ["connect secure"],
"version": ["9.1"],
"fingerprints": [
{
"cpe": "cpe:2.3:a:ivanti:connect_secure:9.1:r15.2:*:*:*:*:*:*",
"vendor": "ivanti",
"product": "connect secure",
"version": "9.1",
"deprecated": false,
"cves": [
{ "cve_id": "CVE-2023-46805", "confirmed": true },
{ "cve_id": "CVE-2024-21887", "confirmed": true },
{ "cve_id": "CVE-2024-21893", "confirmed": true }
]
}
],
"contains_cve": true,
"summary": {
"cve_count": 3,
"confirmed_count": 3,
"fingerprint_count": 1,
"contains_cve": true
},
"asn": "AS64500",
"as_name": "Example ISP",
"as_domain": "test.com",
"country": "United States",
"country_code": "US",
"metadata": {
"status_code": 200,
"title": "Web Interface",
"server": "",
"cert_common_name": "vpn.test.com",
"jarm": "29d3fd00029d29d00042d43d00041d598ac0c1012db967bb1ad0ff2491b3ae"
// ...
}
}
]
}
The record above is the common case: one fingerprint, one CPE, and a set of CVEs that all passed the confidence check. Three things are worth knowing about how the fields relate:
cpe, vendor, product, and version arrays are flattened rollups of everything in fingerprints. When a host has several fingerprints, these arrays hold all of their values together, so don't read across them positionally — use fingerprints when you need to know which version belongs to which product.cve is a plain array of CVE IDs, and cve_confirmed is the same list annotated with per-CVE confidence. The confirmed flag is what the confirmed query parameter filters on.summary is a pre-computed rollup, so you don't have to count array lengths yourself.When no CVE is associated with a fingerprinted service, the cve field is null (not an empty array) and contains_cve is false:
{
"ip": "198.51.100.7",
"hostname": "",
"port": 80,
"timestamp": "2026-09-13T09:10:00Z",
"date_added": "2026-04-02T14:55:11.201Z",
"protocol": "http",
"transport": "tcp",
"cpe": ["cpe:2.3:a:apache:tomcat:10.1.0:*:*:*:*:*:*:*"],
"cve": null,
"vendor": ["apache"],
"product": ["tomcat"],
"version": ["10.1.0"],
"fingerprints": [
{
"cpe": "cpe:2.3:a:apache:tomcat:10.1.0:*:*:*:*:*:*:*",
"vendor": "apache",
"product": "tomcat",
"version": "10.1.0",
"deprecated": false
}
],
"contains_cve": false,
"summary": {
"cve_count": 0,
"confirmed_count": 0,
"fingerprint_count": 1,
"contains_cve": false
},
"asn": "AS64501",
"country": "Germany",
"country_code": "DE"
}
A fingerprinted host with no CVEs is still useful data — it answers "who is running this product" rather than "who is vulnerable". To exclude these records entirely, pass contains_cve=true.
For the complete field reference — including the fingerprints array, the deprecated flag, and what confirmed actually proves — see Response Schema. For the protocol-specific metadata object abbreviated above, see Enrichment Data.