BountyHub Docs
CVE Watcher API and Scopes
Reference for the CveWatcherService ConnectRPC API: list, filter, and fetch CVEs, read vendor and product facets, and manage push channel assignments.
CVE Watcher API and scopes
CVE Watcher is exposed through the ConnectRPC service
bountyhub.cve.v1.CveWatcherService. The Hub UI, the generated TypeScript SDK
(cveWatcherClient), and your own clients all call the same unary methods.
#Transport and authentication
- Protocol: ConnectRPC over HTTPS.
- RPC path:
/<package>.<Service>/<Method>, for example/bountyhub.cve.v1.CveWatcherService/ListCves. - Authentication: a session cookie (browser) or a Personal Access Token sent as
Authorization: Bearer <token>. - Payloads: Connect JSON or protobuf. The examples below use JSON.
Create a PAT with the scopes in the table below — see Personal Access Token scopes for the UI and scope hierarchy.
#Methods and scopes
| Method | Returns | Required scope |
|---|---|---|
ListCves | A page of CVE feed entries | NotificationRo |
GetCve | One CVE feed entry | NotificationRo |
ListCveFacets | Distinct vendor and product values | NotificationRo |
ListCveWatcherNotificationChannels | Your channel assignments | IntegrationRo |
AssignCveWatcherNotificationChannel | The assignment id | IntegrationRw |
UnassignCveWatcherNotificationChannel | Empty response | IntegrationRw |
NotificationRo is the read side of the Notifications scope;
IntegrationRo / IntegrationRw are the Integrations scope. Write scopes
require their read counterpart.
#ListCves
| Field | Type | Notes |
|---|---|---|
severities | CveSeverity[] | Empty or omitted means all severities. |
ransomwareOnly | bool | Restrict to KEV entries with known ransomware use. |
search | string | The query language — see Search and filters. |
pageSize | uint32 | Default 25, maximum 100. |
pageToken | string | Opaque cursor from the previous response. |
Results are ordered by CVE id descending. Pass nextPageToken from the
response as pageToken to continue; an empty token means the last page.
The response contains items and nextPageToken:
uint64 fields such as publishedVersion are strings in Connect JSON.
#CveItem fields
| Field | Type | Meaning |
|---|---|---|
cveId | string | CVE identifier. |
kevAdded | timestamp | Date CISA added the CVE to KEV. Empty for early exploit-sweep entries. |
kevDue | timestamp | CISA remediation deadline. |
vendor, product | string | Normalized from KEV when present, otherwise NVD. |
shortDescription | string | One-line description. |
ransomware | bool | Known ransomware campaign use (KEV). |
cvssV3 | double | CVSS v3 base score, 0.0 – 10.0. |
severity | enum | CVE_SEVERITY_CRITICAL, CVE_SEVERITY_HIGH, CVE_SEVERITY_MEDIUM, CVE_SEVERITY_LOW, CVE_SEVERITY_NONE, or CVE_SEVERITY_UNKNOWN. |
epss | double | FIRST EPSS probability, 0.0 – 1.0. |
exploitAvailable | bool | NVD references public exploit code. |
exploitTier | string | Derived signal: confirmed, likely, watch, or none. |
status | enum | Pipeline position — see below. |
publishedVersion | uint64 | Published version. 0 means never published. |
updated | bool | True when publishedVersion > 1 (a re-announcement). |
userVisibleAt | timestamp | When the CVE entered every user's feed. |
createdAt | timestamp | When the row was first ingested. |
#Status values
| Value | Meaning |
|---|---|
CVE_STATUS_INGESTED | Row exists but has not been announced. Early exploit-sweep rows stay here. |
CVE_STATUS_PUBLIC_PUBLISHED | Public digest stage completed. |
CVE_STATUS_USER_VISIBLE | Visible in every user's in-app feed. |
CVE_STATUS_NOTIFIED | Paid push fan-out completed. |
CVE_STATUS_FAILED | Publication failed; the worker retries. |
#GetCve
Returns { "item": CveItem }, or NOT_FOUND when the CVE is not in the feed.
#ListCveFacets
Returns distinct, alphabetically sorted values for filter autocomplete:
Up to 1,000 values are returned per list. Empty vendor or product values are excluded.
#Manage push channels
Assignments are per user and limited to one channel per integration kind. Assigning a channel of a kind that is already assigned replaces it.
ListCveWatcherNotificationChannels returns items of
CveWatcherNotificationChannelAssignment:
| Field | Meaning |
|---|---|
id | Assignment id, used to unassign. |
notificationChannelId | The assigned notification channel. |
integrationKind | bountyhub.integration.v1.IntegrationKind as an int64, serialized as a string in JSON (Discord, Slack, Mail, Telegram, Webhook). |
notificationChannelName | Channel name, for display. |
integrationName | Integration name, for display. |
Pagination: default 25, maximum 500, ordered by assignment id descending.
#Errors
| Connect code | When |
|---|---|
UNAUTHENTICATED | Missing or invalid session cookie or PAT. |
PERMISSION_DENIED | The PAT lacks the required scope. |
FAILED_PRECONDITION | Assigning a channel on a free plan. |
NOT_FOUND | Unknown CVE, or a notification channel you do not own. |
INVALID_ARGUMENT | Malformed id or page token. |
#Related
- CVE Watcher overview — sources, tiers, and versions.
- Search and filters — the
searchstring. - Push notifications — delivery and channel setup.
- Personal Access Token scopes — scope names and hierarchy.