This guide will help you get started with the NVD CVE API SDK.
go get github.com/deploymenttheory/go-sdk-cveThe NVD API supports two modes:
- Without API Key: 5 requests per 30 seconds
- With API Key: 50 requests per 30 seconds (recommended)
Request an API key from NVD.
Set your API key:
export NVD_API_KEY="your-api-key-here"
export NVD_BASE_URL="https://services.nvd.nist.gov"Create a simple program:
package main
import (
"context"
"fmt"
"log"
"github.com/deploymenttheory/go-sdk-cve/nvd"
)
func main() {
client, err := nvd.NewClientFromEnv()
if err != nil {
log.Fatal(err)
}
vuln, _, err := client.CVEs.GetByID(context.Background(), "CVE-2021-44228")
if err != nil {
log.Fatal(err)
}
fmt.Printf("CVE: %s\n", vuln.CVE.ID)
fmt.Printf("Published: %s\n", vuln.CVE.Published)
fmt.Printf("Description: %s\n", vuln.CVE.Descriptions[0].Value)
}Create config.json:
{
"api_key": "your-api-key-here",
"base_url": "https://services.nvd.nist.gov"
}Use in your code:
cfg, err := nvd.LoadConfigFromFile("config.json")
if err != nil {
log.Fatal(err)
}
client, err := nvd.NewClient(cfg)
if err != nil {
log.Fatal(err)
}cfg := &nvd.Config{
APIKey: "your-api-key-here",
BaseURL: "https://services.nvd.nist.gov",
}
client, err := nvd.NewClient(cfg)
if err != nil {
log.Fatal(err)
}import "github.com/deploymenttheory/go-sdk-cve/nvd/cves"
resp, _, err := client.CVEs.List(context.Background(), &cves.ListRequest{
KeywordSearch: "Apache Log4j",
NoRejected: true,
})resp, _, err := client.CVEs.List(context.Background(), &cves.ListRequest{
CVSSV3Severity: "CRITICAL",
NoRejected: true,
})import "time"
startDate := time.Now().AddDate(0, 0, -7)
endDate := time.Now()
resp, _, err := client.CVEs.List(context.Background(), &cves.ListRequest{
LastModStartDate: &startDate,
LastModEndDate: &endDate,
})resp, _, err := client.CVEs.List(context.Background(), &cves.ListRequest{
HasKEV: true,
NoRejected: true,
})
for _, vuln := range resp.Vulnerabilities {
cve := vuln.CVE
if cve.CISARequiredAction != nil {
fmt.Printf("%s: %s\n", cve.ID, *cve.CISARequiredAction)
}
}import "github.com/deploymenttheory/go-sdk-cve/nvd/cve_history"
startDate := time.Now().AddDate(0, 0, -30)
endDate := time.Now()
resp, _, err := client.CVEHistory.List(context.Background(), &cve_history.ListRequest{
ChangeStartDate: &startDate,
ChangeEndDate: &endDate,
EventName: "Initial Analysis",
})
for _, change := range resp.CVEChanges {
fmt.Printf("%s: %s on %s\n",
change.Change.CVEID,
change.Change.EventName,
change.Change.Created.Format("2006-01-02"))
}The SDK provides helper functions for common error types:
resp, _, err := client.CVEs.GetByID(ctx, "CVE-2021-44228")
if err != nil {
if nvd.IsNotFound(err) {
fmt.Println("CVE not found")
} else if nvd.IsRateLimited(err) {
fmt.Println("Rate limited - wait before retrying")
} else if nvd.IsServerError(err) {
fmt.Println("Server error - retry later")
} else {
log.Fatal(err)
}
}import (
"time"
"go.uber.org/zap"
)
logger, _ := zap.NewProduction()
client, err := nvd.NewClient(
cfg,
nvd.WithTimeout(60*time.Second),
nvd.WithRetryCount(5),
nvd.WithRetryWaitTime(3*time.Second),
nvd.WithRetryMaxWaitTime(60*time.Second),
nvd.WithLogger(logger),
nvd.WithGlobalHeader("X-Application-Name", "MySecurityApp"),
)The SDK automatically handles pagination for you. When you call List(), it fetches all pages:
resp, _, err := client.CVEs.List(context.Background(), &cves.ListRequest{
KeywordSearch: "Windows",
})
// resp.Vulnerabilities contains ALL results, not just the first page
fmt.Printf("Total results: %d\n", len(resp.Vulnerabilities))To limit results, use ResultsPerPage:
resp, _, err := client.CVEs.List(context.Background(), &cves.ListRequest{
KeywordSearch: "Windows",
ResultsPerPage: 100,
})The NVD API enforces rate limits. The SDK automatically retries on 429 responses with exponential backoff.
Best Practices:
- Always use an API key for production
- Use date ranges to fetch only recently modified CVEs
- Implement exponential backoff in your application layer for bulk operations
- Monitor for rate limit errors and adjust request frequency
- Explore the examples directory for more use cases
- Read the API documentation
- Check out the GoDoc for detailed API reference