Your Alert Feed
Watchlist alerts that fired for your organisation, newest first: a new CVE
matched something you watch, or an existing match crossed a notification
threshold. Each alert names what matched (vendor / product / version),
why it matched (match_reason), and why you were notified
(notification_reason).
This is a feed, and it is designed to be polled: pass since with the
created_at of the newest alert you have processed, and you get only what
fired after it — usually an empty page, for one credit.
/v1/my/alertsCost: 1 credit per successful call · Scope: api:org
Query parameters
unseen_onlybooleanoptionaltrue to return only alerts not yet marked seen in the dashboard.
sincestring (timestamp)optionalOnly alerts created strictly after this RFC 3339 timestamp
(e.g. 2026-08-18T00:00:00Z). The polling parameter.
limitintegeroptionalPage size, 1–200. Default 50. Out-of-range is a 400, not a silent clamp.
cursorstringoptionalOpaque pagination cursor from a previous page's next_cursor. Replay the
same filters with it.
Request
curl "https://api.precursorintelligence.com/functions/v1/my/alerts?since=2026-08-18T00:00:00Z" \
-H "Authorization: Bearer $PRECURSOR_API_KEY"Response
{
"data": {
"count": 1,
"items": [
{
"id": "d0187a3c-2b1f-4e2a-8f3d-6a51b9e0c774",
"cve_id": "CVE-2026-31017",
"vulnerability_title": "Nginx HTTP/3 request smuggling",
"severity": "HIGH",
"cvss_score": 8.1,
"epss_score": 0.42876,
"vendor": "f5",
"product": "nginx",
"version": null,
"match_reason": "Watched product: f5/nginx",
"notification_reason": "new_cve",
"published_date": "2026-08-18",
"seen": false,
"created_at": "2026-08-18T06:15:09+00:00"
}
],
"next_cursor": null,
"has_more": false,
"generated_at": "2026-08-19T09:30:00+00:00"
},
"meta": {
"request_id": "8b16efb8-9a6c-4ace-b817-11cbee626d08",
"api_version": "1.3.0",
"credits": { "charged": 1, "remaining": 9998 }
}
}Response fields
data.items[].match_reasonstringoptionalWhat in your watchlist this CVE matched.
data.items[].notification_reasonstringoptionalWhy the alert fired (e.g. a new CVE appeared for a watched product, or a tracked score moved).
data.items[].seenbooleanoptionalWhether the alert has been marked seen in the dashboard. The API is read-only — it cannot mark alerts seen.
data.items[].created_atstringoptionalWhen the alert fired — feed the newest value back as since on your next
poll.
data.next_cursorstring | nulloptionalFor walking history beyond one page. Follow until null, replaying the
same filters. Opaque — do not parse it.
The intended polling loop
- First call:
GET /my/alerts?limit=50, remember the newestcreated_at. - Every poll after:
GET /my/alerts?since=<that timestamp>— one credit, usually zero rows. - Page with
cursoronly if a single poll returnshas_more: true.
Errors
| Status | error | When |
|---|---|---|
| 400 | invalid_since, invalid_limit, invalid_cursor | A parameter failed validation. Free — rejected before billing. |
| 401 | invalid_authorization | Missing or malformed Authorization header. |
| 401 | unauthorized | Invalid/revoked key, IP not allowlisted, or the key lacks the api:org scope. |
| 402 | insufficient_credits | Organisation credit balance is below 1. |
| 405 | method_not_allowed | Only GET and OPTIONS are accepted. |
| 500 | internal | Unexpected server error (credit auto-refunded). |
See Errors for the full error reference.