Find Incidents by Affected Package
Search supply-chain incidents by an affected package name. Matches are
case-insensitive and substring-based, so ethers matches ethers-jss. Results
are returned newest first by the incident's published date.
/v1/supply-chain/packagesCost: 1 credit per successful call
Query parameters
namestringrequiredThe package name (or fragment) to search for. 1 to 200 characters. Matched case-insensitively as a substring against affected package names.
ecosystemstringoptionaldefault: (all)Restrict results to a single package ecosystem (e.g. npm, pypi,
crates, docker, github-actions). A slug of up to 40 characters,
lowercased server-side. Omit to search all ecosystems.
limitintegeroptionaldefault: 50Maximum number of package matches to return. Accepted range: 1–200.
Request
curl "https://api.precursorintelligence.com/functions/v1/supply-chain/packages?name=time&ecosystem=crates&limit=50" \
-H "Authorization: Bearer $PRECURSOR_API_KEY"Response
{
"data": {
"count": 3,
"items": [
{
"incident_id": "crates-2026-02-28-time-utility-typosquats",
"ecosystem": "crates",
"package_name": "time_calibrator",
"affected_versions": ["0.1.0"],
"incident_title": "Rust crates.io time-utility typosquat cluster",
"severity": "high",
"published": "2026-02-28"
},
{
"incident_id": "crates-2026-02-28-time-utility-typosquats",
"ecosystem": "crates",
"package_name": "time-sync",
"affected_versions": ["0.1.0"],
"incident_title": "Rust crates.io time-utility typosquat cluster",
"severity": "high",
"published": "2026-02-28"
},
{
"incident_id": "crates-2026-02-28-time-utility-typosquats",
"ecosystem": "crates",
"package_name": "chrono_anchor",
"affected_versions": ["0.1.0"],
"incident_title": "Rust crates.io time-utility typosquat cluster",
"severity": "high",
"published": "2026-02-28"
}
],
"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 package matches returned (equals items.length).
data.itemsarrayoptionalThe matching affected-package rows, ordered by incident published
descending. Each object contains the fields below. A single incident may
appear multiple times, once per matching package.
data.items[].incident_idstringoptionalIdentifier of the incident this package belongs to. Pass to
GET /v1/supply-chain/incidents/{id} for the full record.
data.items[].ecosystemstringoptionalPackage ecosystem (e.g. npm, pypi, crates, docker,
github-actions).
data.items[].package_namestringoptionalThe affected package name.
data.items[].affected_versionsarrayoptionalArray of affected version strings. May be empty when specific versions were not enumerated.
data.items[].incident_titlestringoptionalTitle of the incident this package belongs to.
data.items[].severitystringoptionalSeverity of the incident: low, medium, high, or critical.
data.items[].publishedstringoptionalISO 8601 date (YYYY-MM-DD) the incident was first published.
data.generated_atstringoptionalISO 8601 UTC timestamp indicating when this response was produced.
Errors
| Status | error | When |
|---|---|---|
| 400 | missing_name | The required name query parameter was not supplied. |
| 400 | invalid_name | name is empty after trimming or exceeds 200 characters. |
| 400 | invalid_ecosystem | ecosystem exceeds 40 characters or contains characters outside [A-Za-z0-9_-]. |
| 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.