List Supply-Chain Incidents
Return recent software supply-chain incidents — compromised packages, registry attacks, typosquats, and maintainer takeovers — newest first, with optional filters for severity and a published-date window.
/v1/supply-chain/incidentsCost: 1 credit per successful call
Query parameters
severitystringoptionaldefault: (all)Filter by incident severity. One of low, medium, high, or critical
(case-insensitive). Omit to return incidents of any severity.
daysintegeroptionaldefault: (no floor)Only return incidents published within the last N days. Accepted range:
1–365. Omit for no date floor (all incidents up to limit).
limitintegeroptionaldefault: 50Maximum number of incidents to return. Accepted range: 1–200.
Request
curl "https://api.precursorintelligence.com/functions/v1/supply-chain/incidents?severity=critical&days=30&limit=50" \
-H "Authorization: Bearer $PRECURSOR_API_KEY"Response
{
"data": {
"count": 2,
"items": [
{
"id": "npm-2026-06-17-mastra-easy-day-js",
"title": "Mastra AI npm scope takeover via `easy-day-js` typosquat dropper",
"summary": "A dormant contributor account, never revoked from the @mastra scope, was used to mass-publish ~144 trojanised @mastra/* releases, each declaring a new easy-day-js dependency whose postinstall hook drops a cross-platform crypto-wallet stealer / RAT.",
"severity": "critical",
"published": "2026-06-17",
"last_updated": "2026-06-18",
"threat_actor": null,
"tags": ["account-takeover", "typosquat", "infostealer", "crypto-wallet-drain"],
"reference": "https://socket.dev/blog/mastra-npm-packages-compromised"
},
{
"id": "npm-2026-06-11-atomic-arch-aur-hijack",
"title": "Atomic Arch: 400+ AUR packages hijacked to ship npm-delivered Rust stealer with eBPF rootkit",
"summary": "Attackers hijacked 400+ orphaned Arch User Repository packages and rewrote their PKGBUILDs to pull three malicious npm dependencies, each dropping a Rust ELF credential stealer with an eBPF rootkit and systemd persistence.",
"severity": "critical",
"published": "2026-06-11",
"last_updated": "2026-06-12",
"threat_actor": null,
"tags": ["maintainer-takeover", "account-takeover", "credential-theft", "infostealer"],
"reference": "https://www.sonatype.com/blog/atomic-arch-npm-campaign-adds-malicious-dependency"
}
],
"generated_at": "2026-05-18T10:24:31.118Z"
},
"meta": {
"request_id": "8b16efb8-9a6c-4ace-b817-11cbee626d08",
"generated_at": "2026-05-18T10:24:31.118Z",
"credits": { "charged": 1, "remaining": 9998 }
}
}Response fields
data.countintegeroptionalNumber of incidents returned (equals items.length).
data.itemsarrayoptionalThe matching incidents, ordered by published descending. Each object
contains the fields below.
data.items[].idstringoptionalStable slug-like identifier for the incident. Pass this to
GET /v1/supply-chain/incidents/{id} for the full record.
data.items[].titlestringoptionalShort human-readable incident title.
data.items[].summarystringoptionalOne-paragraph summary of the incident.
data.items[].severitystringoptionalIncident severity: low, medium, high, or critical.
data.items[].publishedstringoptionalISO 8601 date (YYYY-MM-DD) the incident was first published.
data.items[].last_updatedstring | nulloptionalISO 8601 date of the most recent update, or null if never updated.
data.items[].threat_actorstring | nulloptionalAttributed threat actor, or null when unattributed.
data.items[].tagsarrayoptionalString tags categorising the incident (e.g. typosquat, infostealer).
data.items[].referencestringoptionalPrimary reference URL for the incident.
data.generated_atstringoptionalISO 8601 UTC timestamp indicating when this response was produced.
Errors
| Status | error | When |
|---|---|---|
| 400 | invalid_severity | severity is not one of low, medium, high, critical. |
| 400 | invalid_days | days is not an integer, or is outside the 1–365 range. |
| 400 | invalid_limit | limit is not an integer, or is outside the 1–200 range. |
| 401 | invalid_authorization | The Authorization header is missing or malformed. |
| 401 | unauthorized | The key is invalid, revoked, or the request IP is not on the allowlist. |
| 402 | insufficient_credits | The organisation's credit balance is below 1. |
| 404 | not_found | The route or resource does not exist. |
| 405 | method_not_allowed | Only GET and OPTIONS are accepted. |
| 500 | internal | An unexpected server error occurred. |
See Errors for the full error reference.