Get a Supply-Chain Incident
Fetch the full record for a single supply-chain incident, including the long-form description, impact and recommendation lists, references, attribution, and the list of affected packages.
/v1/supply-chain/incidents/{id}Cost: 1 credit per successful call
Path parameters
idstringrequiredThe incident identifier, as returned by GET /v1/supply-chain/incidents.
A slug-like token matching ^[A-Za-z0-9._-]{1,200}$ (letters, digits, dot,
underscore, hyphen; 1 to 200 characters).
Request
curl https://api.precursorintelligence.com/functions/v1/supply-chain/incidents/npm-2026-06-17-mastra-easy-day-js \
-H "Authorization: Bearer $PRECURSOR_API_KEY"Response
{
"data": {
"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",
"reference": "https://socket.dev/blog/mastra-npm-packages-compromised",
"impact": [
"Cryptocurrency wallet theft: 160+ browser-extension wallets drained on install",
"Cross-platform infostealer + RAT with Windows/macOS/Linux persistence",
"CI/CD runner compromise: postinstall runs automatically during npm install"
],
"recommendation": [
"Run `npm ls easy-day-js` in every project and CI runner — any match indicates execution of the dropper",
"Treat any host that installed an affected @mastra/* version on or after 2026-06-17 01:12 UTC as compromised; rebuild from a known-good image",
"Rotate browser-extension wallet seed phrases, npm tokens, cloud credentials, and any SSH/Git keys accessible from the affected machine"
],
"description": "Between 01:12 and 02:36 UTC on 2026-06-17, an attacker logged into the dormant npm account `ehindero` — a legitimate former Mastra contributor whose owner permissions on the @mastra scope had never been revoked — and mass-published trojanised versions of ~144 packages across the namespace...",
"references_json": [
{
"url": "https://socket.dev/blog/mastra-npm-packages-compromised",
"title": "140+ Mastra npm Packages Compromised in Coordinated Supply Chain Attack",
"publisher": "Socket"
},
{
"url": "https://research.jfrog.com/post/easy-day-js/",
"title": "easy-day-js: Supply Chain Campaign Targets Mastra npm Packages",
"publisher": "JFrog"
}
],
"tags": ["account-takeover", "typosquat", "infostealer", "crypto-wallet-drain"],
"threat_actor": null,
"aliases": ["easy-day-js campaign", "Mastra scope takeover"],
"detected_by": ["Socket", "JFrog", "Snyk", "StepSecurity", "Mend"],
"affected_packages": [
{
"ecosystem": "npm",
"package_name": "@mastra/core",
"affected_versions": ["1.41.0", "1.41.1"]
},
{
"ecosystem": "npm",
"package_name": "easy-day-js",
"affected_versions": ["1.11.22"]
}
]
},
"meta": {
"request_id": "8b16efb8-9a6c-4ace-b817-11cbee626d08",
"generated_at": "2026-05-18T10:24:31.118Z",
"credits": { "charged": 1, "remaining": 9998 }
}
}Response fields
data.idstringoptionalThe stable slug-like identifier for the incident.
data.titlestringoptionalShort human-readable incident title.
data.summarystringoptionalOne-paragraph summary of the incident.
data.severitystringoptionalIncident severity: low, medium, high, or critical.
data.publishedstringoptionalISO 8601 date (YYYY-MM-DD) the incident was first published.
data.last_updatedstring | nulloptionalISO 8601 date of the most recent update, or null if never updated.
data.referencestringoptionalPrimary reference URL for the incident.
data.impactarray | nulloptionalBullet list of strings describing the impact of the incident. May be null.
data.recommendationarray | nulloptionalBullet list of strings with recommended remediation actions. May be null.
data.descriptionstringoptionalLong-form description of the incident.
data.references_jsonarrayoptionalStructured reference list. Each element contains url, title, and
publisher.
data.tagsarrayoptionalString tags categorising the incident.
data.threat_actorstring | nulloptionalAttributed threat actor, or null when unattributed.
data.aliasesarray | nulloptionalAlternative names the incident is tracked under, or null.
data.detected_byarray | nulloptionalVendors and researchers that detected or disclosed the incident, or null.
data.affected_packagesarrayoptionalThe packages affected by the incident. Each element contains ecosystem
(e.g. npm, pypi, crates, docker, github-actions), package_name,
and affected_versions (an array of version strings, which may be empty
when specific versions were not enumerated).
Errors
| Status | error | When |
|---|---|---|
| 400 | invalid_id | The path segment did not match ^[A-Za-z0-9._-]{1,200}$. |
| 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 identifier is valid but no incident with that id exists. |
| 405 | method_not_allowed | Only GET and OPTIONS are accepted. |
| 500 | internal | An unexpected server error occurred. |
See Errors for the full error reference.