Skip to content

GET /v1/organizations/{org_id}/projects/{id}/cases

The handling track (“cases”) of a project’s CVEs: triage status and change history. Returns the project’s cases, shared by the team.

GET /api/v1/organizations/{org_id}/projects/{project_id}/cases
Authorization: Bearer twa_your_key_here
Parameter Type Description
org_id UUID Organization identifier
project_id UUID Project identifier
Parameter Type Description
status string Filter: PENDING, ANALYZING, FIXING, MITIGATED, ACCEPTED, RESOLVED, NOT_APPLICABLE
[
{
"cve_id": "CVE-2024-3094",
"status": "FIXING",
"severity": "CRITICAL",
"notes": "Patch rollout in progress",
"created_at": "2024-06-20T09:00:00Z",
"updated_at": "2024-07-01T14:10:00Z",
"tags": [
{ "id": "018ec0de-0000-7000-8000-0000000000a2", "name": "to-patch", "color": "#f59e0b" }
]
}
]
Field Type Description
cve_id string Related CVE
status string Handling status (see filter above)
severity string | null CVE severity
notes string | null Internal notes
created_at string (ISO 8601) Case creation date
updated_at string (ISO 8601) Last update
tags array<Tag> Team tags assigned to this CVE in the project. Each tag: { id, name, color } (color #rrggbb). Empty array if none.
exception object | null Exception in place, for MITIGATED and for ACCEPTED set outside the accepted-risk register; null otherwise. See below.

MITIGATED is not a fix: the vulnerability is still there, a measure contains it (vendor workaround, WAF rule, feature disabled, network isolation) until an expiry date. The case is neither to do nor closed; the day after the expiry date, without a fix, it reopens by itself (PENDING, or FIXING if it was there). An integration computing “what is still exposed” should therefore count MITIGATED with the open statuses, and exception.expires_on tells until when.

exception field Type Description
nature string contournement (vendor workaround), patch_virtuel (virtual patch), desactivation (feature disabled), segmentation (network isolation), autre (other); aucune (no measure, acceptance only)
measure string | null The measure in place, in plain text
justification string Why
expires_on string (YYYY-MM-DD) Last day of validity (Paris time)
set_at string (ISO 8601) When the exception was set or renewed
GET /api/v1/organizations/{org_id}/projects/{project_id}/cases/{cve_id}
Authorization: Bearer twa_your_key_here

Adds the history field (status changes, oldest to newest):

{
"cve_id": "CVE-2024-3094",
"status": "FIXING",
"history": [
{ "from_status": null, "to_status": "PENDING", "comment": null, "created_at": "2024-06-20T09:00:00Z" },
{ "from_status": "PENDING", "to_status": "FIXING", "comment": "Patch identified", "created_at": "2024-06-25T11:30:00Z" }
]
}
Code Detail Cause
403 La fonctionnalité « cases » n'est pas incluse dans le plan ... Plan without the cases feature
404 Projet introuvable Project does not exist, belongs to another organization, or is outside the key’s project restriction
404 Cas introuvable No case for this CVE on this project

Unresolved cases of the project

Fenêtre de terminal
ORG_ID="018e5678-abcd-7000-8000-000000000001"
PROJECT_ID="018e1234-abcd-7000-8000-000000000010"
curl -s \
-H "Authorization: Bearer twa_your_key_here" \
"https://app.techwatchalert.com/api/v1/organizations/${ORG_ID}/projects/${PROJECT_ID}/cases" \
| jq '.[] | select(.status != "RESOLVED" and .status != "NOT_APPLICABLE") | {cve_id, status, severity, until: .exception.expires_on}'