Docs / Cyber Threat Data API / Endpoints / Retrieve a catalogued vulnerability
Retrieve a catalogued vulnerability
Returns one catalogued vulnerability by id, `<source>:<catalog version>:<CVE id>`. The id names a SNAPSHOT rather than a CVE, so it is stable forever: a published catalog version is never revised, and what this resolves to keeps saying what it said when you stored it. It is also the one path here that does not default to the current catalog, because an id already carries its own — an id you copied out of a page last month still resolves, with the `due_date` that page showed. A CVE since withdrawn from the catalog answers `410` rather than `404`, so a consumer reconciling a compliance list can tell “we held this and it is gone” from “this never existed”.
Parameters
| Parameter | Type | Description |
|---|---|---|
id required |
string | The id from a list response, `<source>:<catalog version>:<CVE id>`. It names a snapshot, so it is stable forever: a published catalog version is never revised, and this keeps resolving to the `due_date` you saw. **The one path that does not default to the current catalog** — an id carries its own. |
Request
curl https://api.softon.dev/v1/cyber/kev/cisa_kev:2026.09.18:CVE-2025-39964 \
-H "Authorization: Bearer $SOFTON_KEY"
req, _ := http.NewRequestWithContext(ctx, "GET", "https://api.softon.dev/v1/cyber/kev/cisa_kev:2026.09.18:CVE-2025-39964", nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("SOFTON_KEY")) res, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer res.Body.Close() var page struct { Data Kev `json:"data"` Meta struct{} `json:"meta"` } if err := json.NewDecoder(res.Body).Decode(&page); err != nil { log.Fatal(err) }
import json, os, urllib.parse, urllib.request url = "https://api.softon.dev/v1/cyber/kev/cisa_kev:2026.09.18:CVE-2025-39964" req = urllib.request.Request(url, headers={ "Authorization": "Bearer " + os.environ["SOFTON_KEY"], }) page = json.load(urllib.request.urlopen(req)) # page["data"] is the object; page["error"] is None on success
const url = new URL("https://api.softon.dev/v1/cyber/kev/cisa_kev:2026.09.18:CVE-2025-39964"); const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SOFTON_KEY}` }, }); if (!res.ok) throw new Error(`${res.status} ${await res.text()}`); const { data, meta } = await res.json();
Response
The envelope is identical on every softon.dev API: data, meta, error. Only the shape inside data changes per dataset — see the response envelope.
{
"data": {
"id": "cisa_kev:2026.09.18:CVE-2026-53362",
"source": "cisa_kev",
"catalog_version": "2026.09.18",
"date_released": "2026-09-18T19:00:05.097400Z",
"catalog_count": 1716,
"cve_id": "CVE-2026-53362",
"vendor_project": "Linux",
"product": "Kernel",
"vulnerability_name": "Linux Kernel Unspecified Vulnerability",
"date_added": "2026-08-27",
"due_date": "2026-08-30",
"short_description": "Linux Kernel contains an unspecified vulnerability that can allow for privilege escalation via IPv6 networking subsystem. This vulnerability can impact multiple products, including but not limited to Suse, Red Hat, and other products using Linux. ",
"required_action": "Apply mitigations in accordance with vendor instructions, ensuring compliance with CISA’s BOD 26-04 Prioritizing Security Updates Based on Risk (see URL in Notes) guidance and CISA’s “Forensics Triage Requirements” (see URL in Notes). Follow applicable BOD 26-04 guidance for cloud services or discontinue use of the product if mitigations are unavailable. Stakeholders are responsible for evaluating each asset's internet exposure and ensuring adherence to BOD 26-04 patching guidelines.",
"known_ransomware_campaign_use": "Unknown",
"forensic_triage": "Yes",
"notes": "This vulnerability affects an open-source component, third-party library, protocol, or proprietary implementation that could be used by different products. For more information, please see: ; https://git.kernel.org/stable/c/14200d435af9a9eeb444f529fc2f689a236b7962; https://git.kernel.org/stable/c/65fb14cbebb0cd0eff903a22d33537ddc8b95769; https://git.kernel.org/stable/c/46f201f8b4c39633a1fa3dc12459f506d470993d; https://git.kernel.org/stable/c/6374fb9edf72c67a118a2c214a0dddd04c921e0a; https://git.kernel.org/stable/c/e9eacf19281ea2498b36291b56c9606118c2d74e; https://git.kernel.org/stable/c/736b380e28d0480c7bc3e022f1950f31fe53a7c5 ; BOD 26-04: https://www.cisa.gov/news-events/directives/bod-26-04-prioritizing-security-updates-based-risk ; Forensics Triage Requirements: https://www.cisa.gov/news-events/directives/bod-26-04-implementation-guidance-prioritizing-security-updates-based-risk ; https://nvd.nist.gov/vuln/detail/CVE-2026-53362",
"cwes": [],
"ingested_at": "2026-09-19T02:00:11.884215Z"
},
"meta": { "request_id": "req_9Fv3" },
"error": null
}
Fields of data
| Field | Type | Description |
|---|---|---|
id |
string | Stable identifier, "<source>:<catalog version>:<CVE id>" — `cisa_kev:2026.09.18:CVE-2025-39964`. Opaque: treat the whole string as the id rather than parsing the parts out of it. **It names a SNAPSHOT of a CVE, not the CVE** — the same CVE has a different id in every catalog version that lists it, so an id you stored keeps resolving to the `due_date` you saw rather than silently moving to a newer one. |
source |
string | Which scraper delivered this catalog. `cisa_kev` is CISA's own published feed. |
catalog_version |
string | CISA's own version label for the published document — `2026.09.18`. Treat it as opaque rather than as a date: it is the publisher's rendering, and `date_released` is the fact. **Pass it back as `?catalog_version=` to pin a walk to one snapshot.** |
date_released |
timestamp | When that catalog was published. A real instant with a time of day in it, not a date — the measured release was 19:00:05 UTC. |
catalog_count |
integer | CISA's own count of the records in that document, **verbatim and never reconciled** with the number of rows served. It has agreed on every fetch measured; if it ever does not, that disagreement is a fact about the upstream document and replacing it with our arithmetic would delete the only evidence of it. |
cve_id |
string | The CVE identifier, `CVE-2025-39964`. **The year in it is the year the CVE was assigned, not the year CISA catalogued it** — `CVE-2002-0367` was added to this catalog in 2022. `date_added` is the other fact and neither is derivable from the other. |
vendor_project |
string · nullable | The upstream's own label for the vendor or project — `Microsoft`, `Linux`, `Cisco`. Free text rather than a taxonomy this platform maintains, so `?vendor=` is a case-insensitive EXACT match: `Apache` and `Apache Tomcat` are two entries here and this API will not collapse them for you. |
product |
string · nullable | The upstream's own label for the affected product. |
vulnerability_name |
string · nullable | CISA's short title for the vulnerability. |
date_added |
date · nullable | The day CISA added this CVE to the catalog. **This is the watermark to sync on** — "what has been catalogued since Tuesday" is a question about the catalogue, where `ingested_at` is a question about us. `?added_from=` takes it. |
due_date |
date · nullable | The Binding Operational Directive deadline for `required_action`. **`?due_to=<today>` is how you ask what is past it.** |
short_description |
string · nullable | CISA's own summary of the vulnerability. |
required_action |
string · nullable | The BOD instruction, verbatim and at length. It usually names the directive it comes from and points at `notes` for the URL. Together with `due_date` this is what makes a row a compliance instrument rather than a vulnerability description — and what makes a stale copy of one harmful rather than merely old. |
known_ransomware_campaign_use |
string | `Known` or `Unknown`, **CISA's own value and not a boolean**. `Unknown` is the agency saying it has no evidence of ransomware use — not that there is none — so publishing it as `false` would put our coercion out under their name. 360 of 1,716 were `Known` on the measured catalog. `?ransomware=known` takes the same vocabulary, lower-cased. |
forensic_triage |
string | `Yes` or `No`, CISA's own value. This one genuinely is a boolean and is still carried as published, so this collection has one rule rather than two. |
notes |
string · nullable | CISA's free-text note, usually carrying the vendor advisory URL and the BOD reference. |
cwes |
array of string · nullable | The upstream's CWE identifiers, `["CWE-362"]`. **An empty array and `null` mean different things and both occur**: `[]` is "CISA classified this and named no weakness" (175 of 1,716 on the measured catalog) and `null` is "CISA did not carry the field". They are not collapsed. |
ingested_at |
timestamp | When this platform stored this snapshot. A whole catalog arrives in one batch, so every row of one `catalog_version` shares this to the microsecond — it dates the snapshot, not the record. |
Try it
Send the request to see a response.