Analysis API
A versioned REST API for running IOC investigations programmatically. Designed for SOAR platforms, SIEMs, scripts, and MCP servers. All endpoints require authentication via a service account API key.
Authentication
All requests must include an Authorization: Bearer <key> header with a service account API key.
A 35-character key prefixed with sb_. Request one from your SOCBuddy administrator. Each key is tied to a named service account and all calls it makes are recorded in the audit log.
curl -H "Authorization: Bearer sb_a3f9c2e1b4d8f7e2a1c3d5e9f2b4a7c8" \ https://socbuddy.example.com/api/v1/plugins
Endpoints
/api/v1/pluginsReturns all enabled plugins. Disabled plugins (missing API key) are excluded. Use this to discover what IOC types are supported before submitting an analysis.
curl -H "Authorization: Bearer sb_…" \ http://localhost:5000/api/v1/plugins
[
{
"name": "virustotal",
"display_name": "VirusTotal",
"supported_ioc_types": ["ip", "domain", "url", "hash"],
"enabled": true,
"categories": ["reputation"]
},
...
]/api/v1/analysisSubmit an IOC for analysis. Fast plugins (most reputation tools) run in parallel and return immediately. Slow plugins (sandboxes) are submitted and appear in pending with a poll URL.
| Field | Type | Required | Description |
|---|---|---|---|
| ioc | string | yes | The indicator value (IP, domain, URL, hash, or email) |
| type | string | yes | One of: ip, domain, url, hash, email |
| plugins | string[] | no | Plugin names to run. Omit to run all enabled plugins that support the IOC type. Unknown names are silently skipped. |
curl -X POST \
-H "Authorization: Bearer sb_…" \
-H "Content-Type: application/json" \
-d '{"ioc": "1.1.1.1", "type": "ip"}' \
http://localhost:5000/api/v1/analysiscurl -X POST \
-H "Authorization: Bearer sb_…" \
-H "Content-Type: application/json" \
-d '{"ioc": "1.1.1.1", "type": "ip", "plugins": ["virustotal", "abuseipdb"]}' \
http://localhost:5000/api/v1/analysis{
"id": "550e8400-e29b-41d4-a716-446655440000",
"ioc": "1.1.1.1",
"type": "ip",
"queried_at": "2026-05-23T10:00:00Z",
"results": {
"virustotal": {
"plugin": "virustotal",
"status": "ok",
"summary": { "malicious": 0, "suspicious": 0, ... },
...
}
},
"pending": {
"joe_sandbox": {
"job_id": "abc123",
"poll_url": "/api/v1/analysis/550e8400-.../pending/joe_sandbox"
}
}
}Per-plugin errors do not fail the request — the errored plugin appears in results with status: "error". If no plugins are applicable, returns 400 no_plugins_available.
/api/v1/analysis/{id}/pending/{plugin}Poll a slow plugin result. Returns 202 while still running, 200 when the result is ready (and stored back in the analysis row).
curl -H "Authorization: Bearer sb_…" \ http://localhost:5000/api/v1/analysis/550e8400-.../pending/joe_sandbox
{ "status": "pending" }{
"status": "ready",
"result": { ...ToolResult }
}Actions
Stateless text-processing utilities. No IOC or plugin required — just send text and get a result back. All action endpoints accept { "text": "..." } and require authentication.
/api/actions/defangReplaces :// → [://], . → [.], @ → [@].
curl -X POST -H "Authorization: Bearer sb_…" -H "Content-Type: application/json" \
-d '{"text": "http://evil.com/path"}' http://localhost:5000/api/actions/defang
// 200
{ "result": "hxxp[://]evil[.]com/path" }/api/actions/refangReverses defanging. Also handles hxxp → http.
curl -X POST -H "Authorization: Bearer sb_…" -H "Content-Type: application/json" \
-d '{"text": "hxxp[://]evil[.]com"}' http://localhost:5000/api/actions/refang
// 200
{ "result": "http://evil.com" }/api/actions/extractExtracts all IOCs from freeform text. Returns a map of type → values. Private IPs are excluded.
curl -X POST -H "Authorization: Bearer sb_…" -H "Content-Type: application/json" \
-d '{"text": "contacted 1.2.3.4 and evil.com"}' http://localhost:5000/api/actions/extract
// 200
{
"indicators": {
"ip": ["1.2.3.4"],
"domain": ["evil.com"]
}
}Error codes
| Status | error | Cause |
|---|---|---|
| 401 | invalid_api_key | Key not found in database |
| 401 | revoked_api_key | Key has been revoked |
| 400 | invalid_request | Missing ioc or type field |
| 400 | invalid_ioc_type | type is not ip / domain / url / hash / email |
| 400 | no_plugins_available | All requested plugins unknown, disabled, or none support this IOC type |
| 404 | not_found | Analysis ID or pending plugin not found |
| 503 | unavailable | Endpoint requires a database (DATABASE_URL not set) |
All error responses have the shape: { "error": "code", "detail": "human readable" }