Threat intelligence API / integrations
curl
The ThreatCluster threat-intelligence API is plain HTTP: 1 request header in, JSON out, with cost and rate information carried in response headers. This page documents that contract with curl, including 1 GET for each data family and the exact status codes you will meet.
Prerequisites
- A free API key. Sign in and mint one under Settings → API. Free keys carry 100 credits a day, 30 requests a minute and a 7-day data window.
- Every request sends the key in the
X-API-Keyheader. - Base URL:
https://threatcluster.io/api/public/v1
Setup
-
Export the key and base URL once per shell (on Windows, see the Windows Terminal guide):
export TC_KEY="tc_live_your_key_here" export BASE="https://threatcluster.io/api/public/v1"
-
Make a first call with
-ito see the response headers alongside the body:curl -si -H "X-API-Key: $TC_KEY" "$BASE/threats?time_filter=24h&limit=1"
Headers
Request: the key is the only header the API needs.
X-API-Key: tc_live_your_key_here
Response: every budgeted response reports what it cost, and free keys also get budget headers so a script can pace itself. Header names are exact; the numbers below are illustrative:
HTTP/2 200 content-type: application/json x-request-cost: 1 x-ratelimit-limit: 100 x-ratelimit-remaining: 87 x-ratelimit-reset: 1788307200
X-Request-Cost is the credits this request spent (0 when an empty result was refunded). X-RateLimit-Limit and X-RateLimit-Remaining track the daily credit budget, and X-RateLimit-Reset is the unix time of the next refill at 00:00 UTC. A 429 adds a Retry-After header.
The data families
# search across clusters, entities and the dark web (5 credits) curl -s -H "X-API-Key: $TC_KEY" "$BASE/search?q=Qilin" # threat clusters (1 credit) curl -s -H "X-API-Key: $TC_KEY" "$BASE/threats?time_filter=24h" # 1 cluster, by the 8-character short id from /threats or /search (1 credit) curl -s -H "X-API-Key: $TC_KEY" "$BASE/threats/93fb80f8" # entity detail (1 credit) curl -s -H "X-API-Key: $TC_KEY" "$BASE/entities/ransomware_group/Qilin" # IOC feed for SIEM or firewall polling (3 credits) curl -s -H "X-API-Key: $TC_KEY" "$BASE/iocs/feed?format=txt" # CVEs, here CISA KEV entries from the last 7 days (1 credit) curl -s -H "X-API-Key: $TC_KEY" "$BASE/vulnerabilities?kev_only=true&days=7" # ransomware leak-site victims (1 credit) curl -s -H "X-API-Key: $TC_KEY" "$BASE/darkweb/ransomware/victims?days=7"
Worked example
/search fans out across the corpus in 1 call and returns typed buckets. Response below trimmed to 1 hit per bucket; the live call returned 30:
curl -s -H "X-API-Key: $TC_KEY" "$BASE/search?q=Qilin"
{
"query": "Qilin",
"clusters": [
{
"short_id": "3a29f452",
"cluster_id": "b2c83a72-8d2c-4913-bb97-47c73a29f452",
"slug": "qilin-ransomware-gang-targets-atf-in-cyberattack-3a29f452",
"ai_title": "Qilin Ransomware Gang Claims Attack on ATF, Major Incident Declared",
"ai_summary": "The Bureau of Alcohol, Tobacco, Firearms and Explosives (ATF) is investigating a major cybersecurity incident after the Qilin ransomware gang claimed…",
"urgency_level": "medium",
"keywords": ["ransomware", "attack"],
"threat_score": 61.25,
"severity_score": 70.0,
"article_count": 31,
"date_range_latest": "2026-08-26T22:35:02+00:00",
"is_new": false,
"is_trending": false,
"entities": {}
}
],
"entities": [
{
"entity_type": "ransomware_group",
"entity_value": "Qilin",
"cluster_count": 124,
"article_count": 202
}
],
"darkweb": [
{
"type": "victim",
"name": "Commission de la construction du Quebec",
"id": "87989ff49ba65be4",
"date": "2026-09-01T03:57:10.128191+00:00",
"group": "qilin",
"country": "CA",
"sector": "Government & Defense"
}
],
"limit": 10,
"total": 30
}
Chain the short_id into /threats/3a29f452, and entity_type plus entity_value into /entities/ransomware_group/Qilin.
Status codes
200: success. The body is JSON except for the txt and csv IOC formats.
401: missing or bad key. Error details arrive wrapped in a detail object:
{"detail": {"error": "Invalid or revoked API key",
"message": "The provided API key is invalid, revoked, or expired"}}
403 insufficient_scope: the key lacks the scope the endpoint needs. The body names required_scope and granted_scopes. Free keys carry threats:read, iocs:read, entities:read, vulns:read and darkweb:read.
403 lookback_exceeded: a by-id lookup of a record older than the free 7-day window:
{"detail": {"error": "lookback_exceeded",
"message": "This threat cluster is older than the 7-day window included with a free API key.",
"lookback_days": 7,
"upgrade_url": "/pricing"}}
422: invalid parameters, for example a /search q that is too short.
429: 2 causes. The per-minute rate limit (30 requests a minute on free keys) and the daily credit budget (daily_budget_exceeded). Both send Retry-After; honour it before retrying.
Costs and limits
Free keys spend a daily budget of 100 credits. Most GETs cost 1 credit; the IOC feed and export, STIX bundles, dark-web keyword hits and trends cost 3; /search costs 5; a dark-web victim enrichment record costs 10. The rate limit is 30 requests a minute and data goes back 7 days. A request that finds nothing refunds its credits and returns X-Request-Cost: 0.
Endpoint reference: /api/public/v1/docs. Bigger windows and budgets: /pricing.