ingest

OSA Webhook API

POST/apis/sigma

Ingest a Security Analytics detector (Sigma) alert

Push webhook. The notification template only needs to send an alert `id`; the server fetches the alert doc, findings (matched Sigma rules) and raw OCSF documents from OpenSearch and stores everything.

Request body

typeenum
sigmadetector
idstring
alert_idstring
detector_namestring
detector_typestring
monitor_idstring
monitor_namestring
trigger_idstring
trigger_namestring
severitystring | number
statestring
finding_idstring
finding_idsstring[] | string
documentstring[] | string
related_doc_idsstring[] | string
start_timestring | number

Responses

201 Stored and fully enriched202 Stored, but enrichment failed (see enrichmentErr on the row)400 Invalid JSON body401 Missing/wrong webhook secret (only when WEBHOOK_SECRET is set)422 Body failed schema validation500 Ingest failed
idstringrequired

Postgres Alert row id (cuid)

typeenumrequired
DETECTORTHREAT_INTELCORRELATION
enrichmentOkbooleanrequired

Whether the OpenSearch enrichment fetches all succeeded (201 vs 202).

indexedbooleanrequired

Whether the searchable copy landed in the app's own OpenSearch index.

cURL
curl -X POST https://osawebhook.defenderx.sentrixsolution.com/apis/sigma \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"sigma","id":"string","alert_id":"string","detector_name":"string","detector_type":"string","monitor_id":"string","monitor_name":"string","trigger_id":"string","trigger_name":"string","severity":"string","state":"string","finding_id":"string"}'
JavaScript
const res = await fetch("https://osawebhook.defenderx.sentrixsolution.com/apis/sigma", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "type": "sigma",
    "id": "string",
    "alert_id": "string",
    "detector_name": "string",
    "detector_type": "string",
    "monitor_id": "string",
    "monitor_name": "string",
    "trigger_id": "string",
    "trigger_name": "string",
    "severity": "string",
    "state": "string",
    "finding_id": "string"
  })
});
const data = await res.json();
Response 201
{
  "id": "string",
  "type": "DETECTOR",
  "enrichmentOk": true,
  "indexed": true
}
POST/apis/threat_intel

Sync recent threat-intel (IOC) findings

**Pull trigger** — a TI monitor notification carries no IOC id, so this endpoint ignores the body and polls the last N minutes of ioc-findings, ingesting them all.

Query parameters

minutesinteger

Look-back window in minutes (default 30). Overlaps are safe (idempotent).

Request body

typestring
idstring
finding_idstring
monitor_idstring
monitor_namestring
ioc_valuestring
ioc_typestring
severitystring | number
related_doc_idsstring[] | string
start_timestring | number

Responses

200 Sync completed401 Missing/wrong webhook secret (only when WEBHOOK_SECRET is set)500 Sync failed
windowMinutesnumberrequired
foundnumberrequired
ingestednumberrequired
failednumberrequired
cURL
curl -X POST https://osawebhook.defenderx.sentrixsolution.com/apis/threat_intel?minutes=0 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"string","id":"string","finding_id":"string","monitor_id":"string","monitor_name":"string","ioc_value":"string","ioc_type":"string","severity":"string","related_doc_ids":"string","start_time":"string"}'
JavaScript
const res = await fetch("https://osawebhook.defenderx.sentrixsolution.com/apis/threat_intel", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "type": "string",
    "id": "string",
    "finding_id": "string",
    "monitor_id": "string",
    "monitor_name": "string",
    "ioc_value": "string",
    "ioc_type": "string",
    "severity": "string",
    "related_doc_ids": "string",
    "start_time": "string"
  })
});
const data = await res.json();
Response 200
{
  "windowMinutes": 0,
  "found": 0,
  "ingested": 0,
  "failed": 0
}
POST/apis/correlation

Sync recent correlation edges

**Pull trigger** — there is no correlation-alert stream, only a high-volume finding–finding graph. Each POST polls recent correlation edges (capped by `max`) and ingests each linked finding pair.

Query parameters

minutesinteger

Look-back window in minutes (default 30). Overlaps are safe (idempotent).

maxinteger

Cap on correlation edges per sync (default 50).

Request body

typestring
idstring
correlation_rule_idstring
correlation_rule_namestring
finding_idsstring[] | string
log_typestring
severitystring | number
start_timestring | number

Responses

200 Sync completed401 Missing/wrong webhook secret (only when WEBHOOK_SECRET is set)500 Sync failed
windowMinutesnumberrequired
foundnumberrequired
ingestednumberrequired
failednumberrequired
cURL
curl -X POST https://osawebhook.defenderx.sentrixsolution.com/apis/correlation?minutes=0&max=0 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"string","id":"string","correlation_rule_id":"string","correlation_rule_name":"string","finding_ids":"string","log_type":"string","severity":"string","start_time":"string"}'
JavaScript
const res = await fetch("https://osawebhook.defenderx.sentrixsolution.com/apis/correlation", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "type": "string",
    "id": "string",
    "correlation_rule_id": "string",
    "correlation_rule_name": "string",
    "finding_ids": "string",
    "log_type": "string",
    "severity": "string",
    "start_time": "string"
  })
});
const data = await res.json();
Response 200
{
  "windowMinutes": 0,
  "found": 0,
  "ingested": 0,
  "failed": 0
}