API documentation

Base URL: https://malware.channel/api/v1

Authentication

Most endpoints need a Bearer token. You can create one in your account settings. /stats and /sources are public.

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://malware.channel/api/v1/iocs?type=ip&per_page=10

Rate limits

60 requests/minute for authenticated endpoints, 30/minute for public ones, 10/minute for exports. Per token. Check X-RateLimit-Remaining in response headers.


Public endpoints

GET /stats

Current numbers. No auth needed.

curl https://malware.channel/api/v1/stats
Response
{
  "total": 557,252,
  "by_type": { "ip": 225,125, "domain": 295,639, ... },
  "by_threat": { "malware": 389,366, "phishing": 161,516, ... },
  "sources": 26,
  "last_24h": 10,540,
  "last_updated": "2026-02-06T12:00:00Z"
}

GET /sources

Lists every feed source with its IOC count and when it last ran.

curl https://malware.channel/api/v1/sources
Response
{
  "count": 26,
  "data": [
    { "name": "phishtank", "ioc_count": 145203, "last_ingested": "2026-02-06T11:45:00Z" },
    { "name": "feodotracker", "ioc_count": 1024, "last_ingested": "2026-02-06T11:30:00Z" },
    ...
  ]
}

IOC endpoints

These endpoints need a token. Pass it as Authorization: Bearer TOKEN.
Common query parameters
Parameter Type Description
qstringSearch IOC values (substring match)
typestringip, domain, url, hash_sha256, hash_md5, hash_sha1, email
threat_typestringmalware, phishing, c2, botnet, ransomware, spam
sourcestringFilter by feed source (e.g. feodotracker, urlhaus)
malware_familystringFilter by malware family (substring match)
min_confidenceintMinimum confidence score (0-100)
sincedatetimeOnly IOCs added after this timestamp (ISO 8601)

Search with filters. Paginate with cursor.

# Search for C2 IPs with high confidence
curl -H "Authorization: Bearer $TOKEN" \
  "https://malware.channel/api/v1/iocs?type=ip&threat_type=c2&min_confidence=80&per_page=50"

Pagination: use after=CURSOR_ID from the next_cursor field to get the next page.

Response
{
  "count": 50,
  "has_more": true,
  "next_cursor": 412350,
  "data": [
    {
      "id": 412400,
      "type": "ip",
      "value": "45.33.32.156",
      "threat_type": "c2",
      "malware_family": "Cobalt Strike",
      "source": "threatfox",
      "confidence": 100,
      "first_seen": "2026-02-06T09:00:11Z",
      "last_seen": "2026-02-06T11:00:00Z",
      "tags": ["cobalt_strike", "threatfox", "AS138415"],
      "metadata": { "reporter": "dyingbreeds_", "reference": "..." }
    },
    ...
  ]
}

GET /iocs/lookup

Exact match on a single value.

curl -H "Authorization: Bearer $TOKEN" \
  "https://malware.channel/api/v1/iocs/lookup?value=45.33.32.156"
Response (not found)
{ "found": false, "value": "8.8.8.8" }

GET /iocs/recent

Latest IOCs. Default: last 24h, max 7 days.

# New ransomware IOCs from the last 6 hours
curl -H "Authorization: Bearer $TOKEN" \
  "https://malware.channel/api/v1/iocs/recent?hours=6&threat_type=ransomware"

GET /iocs/:id

Get a single IOC by ID.

curl -H "Authorization: Bearer $TOKEN" \
  https://malware.channel/api/v1/iocs/412400

POST /iocs/bulk

Check up to 1,000 values in one request.

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"values": ["45.33.32.156", "evil.example.com", "abc123..."]}' \
  https://malware.channel/api/v1/iocs/bulk
Response
{
  "queried": 3,
  "matched": 1,
  "results": {
    "45.33.32.156": { "found": true, "data": { ... } },
    "evil.example.com": { "found": false, "data": null },
    "abc123...": { "found": false, "data": null }
  }
}

Export

GET /export

Export IOCs as JSON, CSV, or plain text (one value per line). Same filters as /iocs. Max 50,000 rows. CSV and TXT are streamed.

# Export C2 IPs as a plain blocklist
curl -H "Authorization: Bearer $TOKEN" \
  "https://malware.channel/api/v1/export?type=ip&threat_type=c2&format=txt" \
  -o c2-blocklist.txt

# Export all ransomware IOCs from last week as CSV
curl -H "Authorization: Bearer $TOKEN" \
  "https://malware.channel/api/v1/export?threat_type=ransomware&since=2026-01-30&format=csv" \
  -o ransomware.csv
Export-specific parameters
formatstringjson (default), csv, or txt
limitintMax rows (default 10,000, max 50,000)

Error responses

Errors return JSON with an error field.

// 400 Bad Request
{ "error": "Missing required parameter: value" }

// 401 Unauthorized
{ "message": "Unauthenticated." }

// 404 Not Found
{ "error": "IOC not found" }

// 429 Too Many Requests
{ "message": "Too many requests." }

Python example

import requests

API = "https://malware.channel/api/v1"
TOKEN = "your-api-token"
headers = {"Authorization": f"Bearer {TOKEN}"}

# Check if an IP is known bad
r = requests.get(f"{API}/iocs/lookup", params={"value": "45.33.32.156"}, headers=headers)
data = r.json()

if data["found"]:
    ioc = data["data"]
    print(f"Threat: {ioc['threat_type']} ({ioc['source']})")
    print(f"Confidence: {ioc['confidence']}/100")
else:
    print("Clean")

# Bulk check a list of IPs
suspects = ["1.2.3.4", "5.6.7.8", "evil.example.com"]
r = requests.post(f"{API}/iocs/bulk", json={"values": suspects}, headers=headers)

for val, result in r.json()["results"].items():
    status = "MALICIOUS" if result["found"] else "clean"
    print(f"  {val}: {status}")