ThreatRecall sits next to your stack.
It does not replace it.
ThreatRecall is the memory layer between your SIEM, CTI platform, and case management tool. It adds durable, evidence-backed recall to the tools you already own — it doesn't compete with them.
Seven integrations. Honest status.
Live = production-tested. Planned = on the roadmap with a target quarter. On request = we'll build it for your pilot.
Pull STIX 2.1 bundles from OpenCTI into ThreatRecall's knowledge graph. Export recall results back as STIX bundles your OpenCTI instance can ingest.
Details →Subscribe ThreatRecall to a MISP feed. New events auto-ingest as KG nodes on your poll interval. Push corrections back via MISP event publish hook.
Details →Forward notable events from Splunk correlation searches to ThreatRecall via HEC. Recall results surface as enrichment context in your ES dashboards.
Details →Trigger a ThreatRecall recall query on every new Sentinel incident. Write the enrichment back as an incident comment via Logic Apps — no custom connector needed.
Details →Bi-directional STIX 2.1 exchange with Chronicle's threat intel feeds. Push ThreatRecall knowledge graph exports into Chronicle's entity graph on a schedule.
Details →Pull adversary intelligence from Falcon Intel into ThreatRecall. Correlate actor TTPs from CrowdStrike's threat library with your workspace's evidence records.
Details →TheHive webhooks push case observables to ThreatRecall on case creation or update. ThreatRecall adds memory context back as a case custom field via the TheHive API.
Details →TLP enforcement across all integrations
TLP:AMBER and TLP:RED data never leaves the workspace boundary via any integration path.
STIX 2.1 exports are blocked for TLP:RED sessions unless the workspace has an explicit RED export grant.
Webhooks, API responses, and all integration payloads honor the same TLP control surface as the UI —
there is no bypass path through an integration connector.
What works today — honest status
| Tool | Ingest (in) |
Recall query (in/out) |
Export (out) |
Webhook trigger | Auth model |
|---|---|---|---|---|---|
|
OpenCTI
Threat intel platform
|
✓ | ✓ | ✓ | ✓ | beta · API key |
|
MISP
Threat sharing platform
|
✓ | ✓ | ✓ | ✓ | API key |
|
Splunk
SIEM
|
beta · HEC | — | ✓ | ✓ | HEC token |
|
Microsoft Sentinel
SIEM
|
✓ | ✓ | beta · Logic Apps | ✓ | Azure AD / app registration |
|
Elastic SIEM
SIEM
|
✓ | — | ✓ | ✓ | API key |
|
TheHive
Case management
|
beta · webhook | — | — | ✓ | API key |
|
Cortex XSOAR
SOAR
|
✓ | ✓ | — | ✓ | API key |
|
Tines
SOAR / automation
|
✓ | ✓ | ✓ | ✓ | API key |
|
Anomali
Threat intelligence
|
✓ | beta | ✓ | ✓ | API key |
✓ Available amber = beta (roadmap) — = not planned
Copy-paste integration examples
All samples execute against a live demo tenant. No fake endpoints.
# POST a natural language recall query # Replace DEMO_API_KEY with your workspace API key # (create at /app/settings/api-keys) curl -X POST https://app.threatrecall.ai/api/recall \\ -H "Authorization: Bearer <DEMO_API_KEY>" \\ -H "Content-Type: application/json" \\ -d '{ "query": "What TTPs does APT29 use for supply chain intrusions?", "max_results": 5 }' # Response: evidence-backed JSON with confidence scores, TLP, sources
{
"results": [
{
"node_id": "kg_node_abc123",
"name": "APT29",
"type": "actor",
"description": "Cozy Bear / The Dukes — Russian state APT group...",
"confidence": 0.94,
"tlp": "AMBER",
"source": "MISP Event #4821",
"linked_evidence_ids": ["ev_001", "ev_002"],
"properties": {
"country": "RU",
"first_activity": "2008",
"associated_ttps": ["T1190", "T1548", "T1047"]
}
}
],
"meta": {
"total": 3,
"query_ms": 18,
"blended": true
}
}
# POST a STIX 2.1 bundle for bulk ingest
# ThreatRecall accepts Identity, Intrusion-Set, Malware,
# Indicator, and Relationship objects
curl -X POST https://app.threatrecall.ai/api/ingest/stix \\
-H "Authorization: Bearer <DEMO_API_KEY>" \\
-H "Content-Type: application/json" \\
-d '{
"type": "bundle",
"id": "bundle--4b0f5e8a-2c3d-4e1f-8a9b-0c2d1e3f4a5b",
"objects": [
{
"type": "intrusion-set",
"spec_version": "2.1",
"id": "intrusion-set--4e8f9a2b-1c3d-4e5f-8a9b-0c2d1e3f4a5b",
"created": "2025-01-15T00:00:00.000Z",
"modified": "2025-01-15T00:00:00.000Z",
"name": "FIN7",
"description": "Carbanak — financially motivated threat group...",
"labels": ["nation-state", "financially-motivated"]
},
{
"type": "malware",
"spec_version": "2.1",
"id": "malware--5f9a0b3c-2d4e-6f1-9b0c-1d3e2f4a6b7c",
"created": "2025-01-15T00:00:00.000Z",
"modified": "2025-01-15T00:00:00.000Z",
"name": "CARBANAK",
"description": "Banking trojan used by FIN7",
"is_family": false
},
{
"type": "relationship",
"spec_version": "2.1",
"id": "relationship--7a0c1d4e-3f6a-7c2-0b9d-5e1f2a3b4c5d",
"created": "2025-01-15T00:00:00.000Z",
"modified": "2025-01-15T00:00:00.000Z",
"source_ref": "intrusion-set--4e8f9a2b-1c3d-4e5f-8a9b-0c2d1e3f4a5b",
"target_ref": "malware--5f9a0b3c-2d4e-6f1-9b0c-1d3e2f4a6b7c",
"relationship_type": "uses"
}
]
}'
# Returns: ingested node/edge counts + any duplicate warnings
{
"status": "ingested",
"bundle_id": "bundle--4b0f5e8a-2c3d-4e1f-8a9b-0c2d1e3f4a5b",
"counts": {
"nodes_created": 2,
"nodes_updated": 0,
"edges_created": 1,
"duplicates_skipped": 0
},
"node_ids": [
"intrusion-set--4e8f9a2b-...",
"malware--5f9a0b3c-..."
],
"ingest_ms": 42
}
STIX 2.1 Export — recall results to OpenCTI/MISP
Query ThreatRecall, then export the results as a valid STIX 2.1 bundle. Drop it directly into OpenCTI or MISP. TLP scope is enforced — RED nodes require explicit workspace grant.
# Step 1: Run a recall query — backend captures the session and returns a recall_id # (Response includes recall_id and max_tlp for the session) curl -X GET https://app.threatrecall.ai/api/recall/search \\ -H "Authorization: Bearer <DEMO_API_KEY>" \\ -G -d "q=APT29 lateral movement" \\ -d "mode=blended" # Response includes: # { "recall_id": "uuid-here", "max_tlp": "TLP:AMBER", "results": [...] } # Step 2: Export the recall session as a STIX 2.1 bundle # The recall_id from Step 1 identifies the session. # TLP:RED sessions are rejected unless workspace has explicit RED export grant. curl -X GET https://app.threatrecall.ai/api/recall/sessions/<RECALL_ID>/export.stix \\ -H "Authorization: Bearer <DEMO_API_KEY>" \\ -H "Accept: application/stix+json;version=2.1" # Response: STIX 2.1 bundle (Content-Type: application/stix+json;version=2.1) # Downloaded as: recall-<id>-<timestamp>.stix.json
{
"type": "bundle",
"id": "bundle--...",
"spec_version": "2.1",
"objects": [
{ "type": "identity", "id": "identity--threatrecall-01", "name": "ThreatRecall", ... },
{ "type": "marking-definition", "id": "marking-definition--...", "definition": { "tlp-marking": { "color": "TLP:GREEN" } } },
{ "type": "note", "id": "note--...", "content": "Recall query #1/1: \"APT29 lateral movement\" (mode: blended, ...)" },
{ "type": "intrusion-set", "spec_version": "2.1", "id": "intrusion-set--...", "created": "...", "name": "APT29", ... },
{ "type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--...", "name": "T1021 - Remote Services", ... },
{ "type": "relationship", "spec_version": "2.1", "id": "relationship--...", "relationship_type": "uses", "source_ref": "...", "target_ref": "..." }
]
}
# Step 1: Register a webhook endpoint for new evidence events # Pro tier — create at /app/settings/webhooks curl -X POST https://app.threatrecall.ai/api/webhooks \\ -H "Authorization: Bearer <DEMO_API_KEY>" \\ -H "Content-Type: application/json" \\ -d '{ "url": "https://your-soar.example.com/threatrecall-webhook", "events": ["evidence.ingested", "node.created"], "secret": "your_signing_secret" }' # Step 2: ThreatRecall POSTs here when new evidence matches your criteria # Payload signed with HMAC-SHA256 using your secret: # POST /your-webhook-url # X-ThreatRecall-Signature: sha256=abc123... # X-ThreatRecall-Event: evidence.ingested # X-ThreatRecall-Timestamp: 1735689600 # Payload (example): { "event": "evidence.ingested", "timestamp": "2025-01-15T12:00:00Z", "data": { "node_id": "kg_node_abc123", "name": "BlackCat Ransomware", "type": "malware", "tlp": "GREEN", "source": "OpenCTI feed", "confidence": 0.88 } }
{
"event": "evidence.ingested",
"timestamp": "2025-01-15T12:00:00.000Z",
"workspace_id": "ws_demo_public",
"data": {
"node_id": "kg_node_abc123",
"name": "BlackCat Ransomware",
"type": "malware",
"description": "ALPHV / BlackCat — ransomware-as-a-service group...",
"confidence": 0.88,
"tlp": "GREEN",
"source": "OpenCTI Feed: Ransomware Intel",
"linked_evidence_ids": ["ev_99"],
"properties": {
"first_seen": "2021-Q4",
"region": "Ransomware-as-a-Service",
"ttp_codes": ["T1486", "T1490"]
}
},
"delivery_attempt": 1
}
OpenCTI — bi-directional STIX 2.1
Direction: Push (OpenCTI → ThreatRecall) + Pull (ThreatRecall → OpenCTI export).
Payload: STIX 2.1 bundle (Identity, Intrusion-Set, Malware, Indicator, Relationship objects).
Evidence chain: Source URL, TLP marking-definition, confidence score, and ingested_at timestamp are preserved as STIX custom properties on each object.
# Minimal config: pull from an OpenCTI workspace via STIX 2.1 API # Replace with your OpenCTI instance URL and API token curl -X POST https://app.threatrecall.ai/api/ingest/stix \\ -H "Authorization: Bearer $THREATRECALL_API_KEY" \\ -H "Content-Type: application/json" \\ -d '{ "source": "opencti", "source_url": "https://opencti.internal.example.com", "stix_bundle_url": "https://opencti.internal.example.com/bundles/export/global/stix2/1/simple", "auth_header": "Authorization: Bearer YOUR_OPENCTI_TOKEN" }' # ThreatRecall fetches the STIX bundle and ingests as KG nodes. # Duplicate nodes are detected by STIX id — safe to re-run. # Docs: /docs/api (OpenCTI section)
Splunk ES — HEC forward + recall enrichment
Direction: Push (Splunk → ThreatRecall via HEC) + Pull (recall results enrich ES dashboards).
Payload: JSON (CEF-compatible notable event format).
Evidence chain: Splunk index, sourcetype, host, and _time are preserved as source and ingested_at fields on the resulting KG node.
Configure Splunk to POST notable events to ThreatRecall on every correlation search. Works with any search — no custom add-on needed.
# props.conf — index events containing IOCs # Add to $SPLUNK_HOME/etc/system/local/props.conf [source::...threat_intel_feed] TRANSFORMS-threatrecall = threatrecall_ioc_forward # outputs.conf — send to ThreatRecall ingest endpoint # Add to $SPLUNK_HOME/etc/system/local/outputs.conf [tcpout:threatrecall] server = app.threatrecall.ai:443 sslCertCA = /opt/splunk/etc/auth/splunkcloud/secureAAA.crt # transforms.conf — filter and shape events # Add to $SPLUNK_HOME/etc/system/local/transforms.conf [threatrecall_ioc_forward] REGEX = (?i)(ioc|indicator|malware|apt) DEST_KEY = _JSON FORMAT = json_events = true # Or use a scripted alert in Splunk — run every 5 min: # $SPLUNK_HOME/bin/scripts/threatrecall_hec.py curl -X POST https://app.threatrecall.ai/api/ingest/bulk \\ -H "Authorization: Bearer $THREATRECALL_API_KEY" \\ -H "Content-Type: application/json" \\ -d "{\"source\":\"splunk_hec\",\"events\": $(cat /tmp/splunk_notables.json)}"
MISP — subscribe to a feed + push corrections back
Direction: Pull (MISP → ThreatRecall on poll interval) + Push (ThreatRecall corrections → MISP via publish hook).
Payload: MISP JSON event format (auto-converted to STIX 2.1 on ingest).
Evidence chain: MISP org, event ID, tags, and TLP tag are preserved as source, tlp, and confidence fields on each node.
Configure a pull-based MISP feed subscription. ThreatRecall polls on your interval and ingests matching events as KG nodes.
# MISP feed configuration (Admin → Feeds → Add feed) # Feed URL (replace with your internal MISP URL): https://misp.internal.example.com/feeds/download # Authentication headers: Authorization: Bearer <YOUR_MISP_AUTH_KEY> X-MISP-Org: YourOrg # Sync settings: Fixed server: https://app.threatrecall.ai/api/ingest/misp Sync interval: 60 min (configurable, 15min–24h) Filter tags: +threat-intel,-false-positive,-osint-auto # Alternatively, push via MISP event publish hook: # /usr/local/bin/misp2threatrecall.py --misp-url https://misp.internal # Run via cron: */15 * * * * /usr/local/bin/misp2threatrecall.py curl -X POST https://app.threatrecall.ai/api/ingest/misp \\ -H "Authorization: Bearer $THREATRECALL_API_KEY" \\ -H "Content-Type: application/json" \\ -d '{"feed_id": "misp-ransomware-feed", "event_ids": []}' # Empty event_ids = ingest last 24h of events matching feed filters
Microsoft Sentinel — Logic App recall enrichment
Direction: Pull (Sentinel incident → ThreatRecall recall) + Push (recall result → Sentinel incident comment).
Payload: JSON (ThreatRecall recall API response written as Sentinel incident comment).
Evidence chain: Source TLP, confidence, and evidence record IDs from the recall result are included in the comment body — analysts can audit the provenance without leaving Sentinel.
Trigger a ThreatRecall query every time Sentinel creates an incident. Write the recall result back as an incident comment.
# Logic App trigger: "When an Azure Sentinel incident is created" # Step 1: Parse incident title for the recall query TriggerBody()?['Title'] # Step 2: HTTP action → ThreatRecall recall endpoint POST https://app.threatrecall.ai/api/recall Headers: Authorization: Bearer <THREATRECALL_API_KEY> Content-Type: application/json Body: { "query": "@{triggerBody()?['Title']}", "max_results": 3, "tlp_filter": ["GREEN", "AMBER", "WHITE"] } # Step 3: Parse response → add incident comment # Azure Sentinel: Add comment to incident Incident Client: Incident ARM ID: @{triggerBody()?['ResourceId']} Comment: ThreatRecall Analysis: @{body('ThreatRecall_Recall')?['results']?['name']} Confidence: @{body('ThreatRecall_Recall')?['results']?['confidence']} TLP: @{body('ThreatRecall_Recall')?['results']?['tlp']} Source: @{body('ThreatRecall_Recall')?['results']?['source']} # Error handling: if recall returns empty, skip comment (no-op)
Google Chronicle — STIX 2.1 feed (Planned · Q3 2026)
Direction: Push (ThreatRecall → Chronicle threat intel feed) + Pull (Chronicle entity graph → ThreatRecall on schedule).
Payload: STIX 2.1 bundle via Chronicle's Ingestion API.
Evidence chain: TLP markings are mapped to Chronicle's confidence and severity fields. Source and timestamp are preserved in the bundle's object properties.
This integration is on the Q3 2026 roadmap. If Chronicle is in your stack, flag it in the pilot form — design partners shape the spec.
# Planned: push ThreatRecall STIX export to Chronicle Ingestion API
# Chronicle STIX 2.1 endpoint (target design — subject to change):
curl -X POST https://malachiteingestion-pa.googleapis.com/v2/unstructuredlogentries:batchCreate \\
-H "Authorization: Bearer $CHRONICLE_OAUTH_TOKEN" \\
-H "Content-Type: application/json" \\
-d "$(curl -sS https://app.threatrecall.ai/api/recall/sessions/<RECALL_ID>/export.stix \\
-H 'Authorization: Bearer '$THREATRECALL_API_KEY \\
| python3 -c 'import sys,json; d=json.load(sys.stdin); print(json.dumps({"entries":[{"logText":json.dumps(d),"collectionTime":"'"$(date -u +%FT%TZ)"'"}],"log_type":"STIX"}))' \\
)"
# Until Q3 2026: use the generic STIX export → manual Chronicle import.
# Flag in your pilot application to get early access.
CrowdStrike Falcon — adversary intel pull (On request)
Direction: Pull (CrowdStrike Falcon Intel API → ThreatRecall).
Payload: CrowdStrike JSON actor/indicator objects, normalized to ThreatRecall KG node format on ingest.
Evidence chain: CrowdStrike actor slug, malicious confidence score, and kill chain stage are mapped to source, confidence, and node properties.
This integration will be built for design partner pilots that have CrowdStrike Falcon Intel in their stack. Select "CrowdStrike" in the pilot application form and we'll scope it in week one.
# On request: pull adversary actors from Falcon Intel API
# Requires FALCON_CLIENT_ID + FALCON_CLIENT_SECRET (Falcon OAuth2)
# Step 1: Get OAuth2 token
TOKEN=$(curl -s -X POST https://api.crowdstrike.com/oauth2/token \\
-d "client_id=$FALCON_CLIENT_ID&client_secret=$FALCON_CLIENT_SECRET" \\
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
# Step 2: Pull actor objects and forward to ThreatRecall ingest
# (connector provided during pilot onboarding)
curl -s "https://api.crowdstrike.com/intel/v1/actors?limit=100&fields=id,name,description,motivations,kill_chain" \\
-H "Authorization: Bearer $TOKEN" | \\
curl -X POST https://app.threatrecall.ai/api/ingest/crowdstrike \\
-H "Authorization: Bearer $THREATRECALL_API_KEY" \\
-H "Content-Type: application/json" \\
-d @-
# /api/ingest/crowdstrike endpoint ships with pilot connector package.
TheHive — webhook push + recall enrichment
Direction: Push (TheHive webhook → ThreatRecall on case event) + Pull (ThreatRecall recall → TheHive case custom field).
Payload: TheHive JSON event (observables, case metadata), normalized on ingest. Recall result written back as JSON to TheHive case via PATCH.
Evidence chain: TheHive case ID, observable type, and TLP tag are preserved as source, source_type, and tlp on the resulting KG node.
# Step 1: In TheHive → Administration → Webhooks, add:
# URL: https://app.threatrecall.ai/api/ingest/thehive
# Authentication: Add Authorization header with your ThreatRecall API key
# TheHive sends this JSON payload on case:create / observable:create events:
{
"operation": "Creation",
"objectType": "Observable",
"objectId": "~12345",
"object": {
"dataType": "domain",
"data": "malicious-domain.example.com",
"tlp": 2,
"ioc": true,
"tags": ["apt29", "supply-chain"]
},
"details": {
"caseId": "~67890",
"title": "APT29 Phishing Campaign"
}
}
# Step 2: ThreatRecall ingests the observable as a KG node (type: ioc).
# TLP 0=WHITE, 1=GREEN, 2=AMBER, 3=RED — mapped to ThreatRecall TLP fields.
# Step 3: ThreatRecall POSTs recall enrichment back to TheHive case:
PATCH https://thehive.internal.example.com/api/v1/case/~67890/customField
{
"threatrecall_context": {
"recall_result": "APT29 actor node matched. Confidence: 0.92. TLP: AMBER.",
"recall_id": "uuid-here",
"recall_ts": "2026-05-29T21:00:00Z"
}
}
What we do not do
ThreatRecall adds durable CTI memory to your stack. It does not replicate the functions of the tools below.
We are not a SIEM.
We don't ingest raw logs, build dashboards, or run correlation searches. We answer questions about what you already know.
We do not store raw logs.
ThreatRecall is a knowledge graph. Forensics data stays in Splunk, Sentinel, or Elastic — we add context, not storage.
We do not replace MISP as a sharing platform.
We consume MISP feeds and can export back. But ThreatRecall is not a MISP instance — that's yours.
We do not replace OpenCTI as a graph store.
We are a memory layer that works alongside OpenCTI. ThreatRecall and OpenCTI can run in parallel — we do not compete for the same role.
We do not run detection rules.
We ingest IOCs and TTPs, we don't evaluate firewall logs. Detection belongs in your SIEM — we supply the intel that powers it.
We do not auto-enrich tickets.
We expose webhooks and a REST API. Your SOAR (Tines, Cortex, TheHive) decides when to call us and what to do with the answer.