> ## Documentation Index
> Fetch the complete documentation index at: https://docs.opensourcemalware.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Threat feed: query the latest verified OSM threats

> Poll for verified threat reports added within a time window.

The `threat-feed` endpoint returns verified threats added to the OSM database within a rolling time window. Poll it every hour with `hours=1` to never miss a threat.

<Note>
  Subscription Required: This is a paid endpoint available to Researcher Pro and Enterprise users.
</Note>

Use this endpoint to:

* **Keep blocklists current:** Pull newly verified threats on a schedule and automatically update your block rules without manual review.
* **Power automated alerting:** Feed new threats into your SIEM, SOAR, or internal alerting pipeline as they are verified.
* **Recover missed threats:** Use a larger `hours` value (up to 24) to catch up after a poller outage without re-ingesting your entire threat history.

**Endpoint**

```text theme={null}
GET https://api.opensourcemalware.com/functions/v1/threat-feed
```

**Required header**

```text theme={null}
Authorization: Bearer osm_your_token
```

Alternative: Pass API key as query parameter: `?apikey=osm_your_token`

> **Paid Access Required** This endpoint requires a Core or Enterprise API key. Standard API tokens will receive a `403 Forbidden` response.

## Query parameters

`ecosystem` is required:

* Valid values for packages: `npm`, `pypi`, `crates`, `nuget`, `maven`, `go`, `packagist`, `rubygems`, `vscode`, `openvsx`, `brew`, and `skills`.
* Valid  values for other malicious assets: `repository` and`container`.
* Not supported: `domain`, `wallet`, `ip`, `url`.

Optional parameters include: -`hours` let's you select a look back window between 1 and 24 hours. If you don't specify a value, the default is `1`. For example, `hours=6` returns all threats verified in the last 6 hours.

* `unverified` provides threat submissions that haven't been verified by the OpenSourceMalware team. See [Get unverified scans](#get-unverified-scans) for instructions.

## Response example

### Success (200)

```json theme={null}
{
  "count": 5,
  "window_hours": 1,
  "ecosystem": "npm",
  "from": "2026-04-11T10:00:00.000Z",
  "to": "2026-04-11T11:00:00.000Z",
  "threats": [
    {
      "id": "bbf96529-1912-4a64-af1b-8cd8f6b96ae0",
      "created_at": "2026-06-23T19:54:45.144851+00:00",
      "updated_at": "2026-06-23T20:01:26.46+00:00",
      "report_type": "package",
      "severity_level": "high",
      "status": "verified",
      "verified_at": "2026-06-23T20:01:26.46+00:00",
      "first_seen": "2026-06-23T19:54:41.625+00:00",
      "last_seen": null,
      "registry": "npm",
      "resource_identifier": "npm/ts-predict-helper",
      "package_name": "ts-predict-helper",
      "download_count": null,
      "published_date": null,
      "tags": [
        "npm",
        "compromised-account",
        "suspicious-metadata"
      ],
      "version_info": "0.0.1-security",
      "source_id": null,
      "threat_description": "Malicious package detected.",
      "payload_description": "ADDITIONAL FINDINGS\n  - Brand New Package",
      "evidence_references": null,
      "verified_by": "6mile",
      "osv_advisory_url": "https://osv.dev/vulnerability/MAL-2026-6322",
      "ghsa_advisory_url": null,
      "researcher": null,
      "researcher_organization": null,
      "malicious_dependencies": []
    }
  ]
}
```

Depending on how you've integrated the API, you may see a blank `version_info` field or a null response. This indicates that all versions are malicious, which is common with malicious assets.

### 401 — Missing API token

```json theme={null}
{ "error": "API token required. Provide token in Authorization header or apikey query parameter." }
```

### 401 — Invalid or inactive token

```json theme={null}
{ "error": "Invalid or inactive API token" }
```

### 403 — Requires Pro/Editor/Admin

```json theme={null}
{ "error": "Access denied. This endpoint requires Pro, Editor, or Admin access." }
```

### 400 — Missing `threat_id`

```json theme={null}
{ "error": "Missing required parameter: threat_id" }
```

### 400 — Invalid UUID

```json theme={null}
{ "error": "Invalid threat_id format. Must be a valid UUID." }
```

### 404 — Not found or not verified/modified

```json theme={null}
{ "error": "Threat not found or not in verified/modified status." }
```

## cURL examples

Poll for npm threats in the last hour (default):

```text theme={null}
curl -H "Authorization: Bearer osm_your_token" \
  "https://api.opensourcemalware.com/functions/v1/threat-feed?ecosystem=npm"
```

Get PyPI threats from the last 6 hours:

```text theme={null}
curl -H "Authorization: Bearer osm_your_token" \
  "https://api.opensourcemalware.com/functions/v1/threat-feed?ecosystem=pypi&hours=6"
```

Get all repository threats from the last 24 hours:

```text theme={null}
curl -H "Authorization: Bearer osm_your_token" \
  "https://api.opensourcemalware.com/functions/v1/threat-feed?ecosystem=repositories&hours=24"
```

<Tip>
  * **Never miss a threat:** Set up a cron job to call this endpoint every hour with `hours=1`. Each call returns all threats verified since the last poll.
  * **Catch-up window:** If your poller goes down, use a larger `hours` value (up to 24) to recover any missed threats.
  * **No duplicates:** Results are filtered by `verified_at` timestamp, so overlapping windows will return the same threats -- deduplicate by threat `id`.
</Tip>

## Get unverified scans

Verified threats are accurate, but they lag behind real-time scanning by however long human review takes. If you'd rather trade a small false-positive risk for the freshest possible signal, you can pull scan results directly from OpenSourceMalware's detection pipeline before a researcher has confirmed them.

<Warning>
  Blocking unconfirmed malware can result in sending false positives to your development team and can lead to loss of trust. Be thoughtful about how you use this capability. For example, consider creating a "suspicious asset" policy that requires a time-based hold on downloading the package while you wait for OpenSourceMalware to make a determination.
</Warning>

Add `unverified=1` to any `threat-feed` request:

```text theme={null}
curl -H "Authorization: Bearer osm_your_token" \
  "https://api.opensourcemalware.com/functions/v1/threat-feed?ecosystem=npm&hours=24&unverified=1"
```

## STIX format

The OSM API also supports returning threat feed data in STIX (Structured Threat Information Expression) format, making it compatible with threat intelligence platforms and SIEMs that consume STIX bundles. To request STIX output, contact [info@osmsecurity.com](mailto:info@osmsecurity.com) for access details.

<Tip>
  Combine the threat feed with your internal tooling to build automated alerting pipelines. For example, pull the feed on a schedule, diff it against your last known state, and trigger alerts or block-list updates only for new entries. This keeps your security controls current without requiring manual review of every new threat report.
</Tip>
