コンテンツにスキップ

API Reference

CSIRT-Pro exposes a REST API for programmatic access to platform features. The endpoints fall into two roles: a high-performance core API for ingestion and search, and a management API for everything else.


Base URLs

API Base URL Description
Management API https://<your-domain>/api/ Organization, cases, playbooks, pipelines, and configuration
Core API (v2) https://<your-domain>/api/v2/ High-performance ingestion and search

Authentication

OAuth2 / OIDC (SSO)

CSIRT-Pro authenticates through an OIDC identity provider using the OAuth2 Authorization Code flow with PKCE.

Login Flow:

  1. The client calls GET /api/auth/login/?json=1 to obtain the authentication URL.
  2. The user authenticates at the identity provider.
  3. The provider redirects back with an authorization code.
  4. The client calls GET /api/auth/callback/?code=xxx to complete the exchange.
  5. The server exchanges the code for tokens and sets the jwt cookie.

Verified against the running build

A successful POST /api/auth/token/ returns 201 and sets the session JWT in the jwt cookie (not access_token). The same cookie is accepted by both the management API and the core API (v2).

Token Lifetimes

Token Lifetime Purpose
Access Token 24 hours API request authentication
Refresh Token 1 day Renew the access token

API Key Authentication

For programmatic access, use API keys created from the Organization management screen. Each key carries a scope that controls its permissions.

curl -H "X-API-Key: <api_key>" \
  "https://<domain>/api/user/<user_id>/search/"

The web UI uses jwt cookie-based session authentication.

curl -H "Cookie: jwt=<jwt_token>" \
  "https://<domain>/api/user/<user_id>/search/"

Common Headers

Header Description
Content-Type application/json
Cookie jwt=<jwt>
X-API-Key <api_key> (when using API keys)
X-SOCEngine-Tags Tag-based filter (JSON format)

Error Responses

{
  "error": "Error message",
  "detail": "Detailed description"
}
Status Code Description
200 Success
201 Created
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
429 Rate Limit Exceeded
500 Internal Server Error

Auth Endpoints

Login

GET /api/auth/login/

Query parameter: json=1 to return auth_url as JSON.

Callback

GET /api/auth/callback/?code=xxx

Token Exchange

POST /api/auth/token/

Token Refresh

POST /api/auth/refresh/

Logout

POST /api/auth/logout/

Auth Status

GET /api/auth/status/

Response:

{
  "authenticated": true,
  "user_id": "user-uuid",
  "organization_id": "org-uuid"
}

Current User

GET /api/auth/current-user/

Passkey (WebAuthn) Endpoints

Availability

Passkey support is provided primarily by proxying the authentication provider via me/passkeys (list / register / verify / delete). The standalone passkey login routes below may be disabled in the current build. Verify against the implementation before relying on them.

Operation Method Endpoint
Register options POST /api/auth/passkey/register/options/
Register complete POST /api/auth/passkey/register/
Login challenge POST /api/auth/passkey/login/options/
Login complete POST /api/auth/passkey/login/

Ingestion Endpoints

The ingestion endpoint requires a pipeline_id. Accepted records flow through a streaming ingestion bus to an ingestion worker before landing in the log store.

Single Record (Core API v2)

POST /api/v2/ingest?pipeline_id=<pipeline_id>

Body: Any JSON object.

curl -X POST "https://<domain>/api/v2/ingest?pipeline_id=abc-123" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: <api_key>" \
  -d '{"timestamp": "2025-01-15T10:30:00Z", "src_ip": "192.168.1.100", "action": "DENY"}'

Batch (Core API v2)

POST /api/v2/ingest/batch

Body:

{
  "pipeline_id": "<pipeline_id>",
  "records": [
    {"timestamp": "2025-01-15T10:30:00Z", "src_ip": "192.168.1.100"},
    {"timestamp": "2025-01-15T10:30:01Z", "src_ip": "192.168.1.101"}
  ]
}

Bulk (Management API)

POST /api/user/<user_id>/bulk/<pipeline_name>/

Body: JSON array of records.

Health Check

GET /api/v2/health

Splunk HEC-Compatible Endpoints (Core API v2)

CSIRT-Pro exposes Splunk HTTP Event Collector (HEC) compatible endpoints. Authenticate with Authorization: Splunk <token>, where the token is treated as an API key with the ingest scope.

GET  /services/collector/health            # returns {"code":17,"text":"HEC is healthy"}
POST /services/collector
POST /services/collector/event
POST /services/collector/event/1.0
POST /services/collector/raw
POST /services/collector/raw/1.0

Verified against the running build & compatibility scope

GET /services/collector/health returns the Splunk code 17, and event endpoints return Splunk-style codes (e.g. {"code":7,"text":"Incorrect index"}). Indexer acknowledgement (/services/collector/ack), data channels, and time/host/source/sourcetype metadata propagation are NOT supported. Do not describe this as fully Splunk-compatible.

Supported Content Types

Format Content-Type
JSON application/json
NDJSON application/x-ndjson
Plain Text text/plain

Search Endpoints

POST /api/user/<user_id>/search/

Body:

Field Type Required Description
expr string Yes PRQL query expression
runAs string No Organization UUID (admin cross-org query)
is_date_histogram boolean No Date histogram mode
system boolean No Query system tables

Response: a columnar binary stream (Content-Type: application/vnd.apache.arrow.stream).

import pyarrow as pa
import requests

response = requests.post(
    "https://<domain>/api/user/<user_id>/search/",
    headers={"X-API-Key": "<api_key>"},
    json={"expr": "from `firewall_logs` take 10"}
)

reader = pa.ipc.open_stream(response.content)
table = reader.read_all()
df = table.to_pandas()

Sigma Rule Conversion

POST /api/sigma

Body: a Sigma rule in YAML format (as a string).


Case Endpoints

List Cases

GET /api/user/<user_id>/messages/

Query Parameters:

Parameter Type Description
offset integer Pagination offset
limit integer Number of records
dateFrom string Start date (ISO 8601)
dateTo string End date (ISO 8601)
status string open / inprogress / resolved
classification string Classification filter
contained string Containment status filter
stats boolean true returns statistics instead of records

Create Case

POST /api/user/<user_id>/messages/

Body:

{
  "title": "Suspicious Login Activity",
  "description": "Multiple failed login attempts from IP 10.0.0.50",
  "status": "open",
  "classification": "intrusion-attempt",
  "tags": {"severity": "high"}
}

Update Case

PATCH /api/user/<user_id>/messages/

Body:

{
  "message_id": "msg-001",
  "status": "inprogress"
}

Delete Case

DELETE /api/user/<user_id>/messages/
GET /api/user/<user_id>/messages/<message_id>/similar/

Ranks past cases by similarity of the case text and returns a similarity_score.

AI Recommendations

GET /api/user/<user_id>/messages/<case_id>/recommend/

Returns suggested responses ranked by a weighted blend of case similarity and access history. This is a scoring heuristic, not a separate inference model.

High-Performance Case List (Core API v2)

GET /api/v2/user/<user_id>/messages/

Same query parameters as the management API, optimized for large result sets.


Playbook Endpoints

List Playbooks

GET /api/user/<user_id>/playbook/

Create Playbook

POST /api/user/<user_id>/playbook/

Body:

{
  "name": "Block Malicious IP",
  "conditions": [
    {
      "type": 1,
      "name": "check_ip",
      "code": "import requests\nresponse = requests.get(...)\noutput = response.json()"
    }
  ],
  "trigger": [{"type": 104, "schedule": "*/5 * * * *"}],
  "environment_variables": [
    {"key": "API_KEY", "value": "your-api-key"}
  ]
}

Node types: the node type is a numeric enum. Beyond the basics (2 = Condition, 4 = Loop, 5 = End), action nodes cover many operations: threat hunting (Sigma search), search, case create/reply, transform / jinja2, variable operations, script (Python, run in an isolated function-execution environment), call_playbook, pipeline, ueba_lambda, and more. See the visual editor for the full list.

Trigger types: Threat Hunting, Schedule (cron, with a schedule field), Webhook, and Case.

Approval before write actions

Playbook actions that change state through connected systems are approval-gated (request, approve, then apply). The platform does not automatically remediate, block traffic, or close cases.

Get Playbook

GET /api/user/<user_id>/playbook/<playbook_id>/

Update Playbook

PUT /api/user/<user_id>/playbook/

Delete Playbook

DELETE /api/user/<user_id>/playbook/

Execute Playbook

POST /api/user/<user_id>/playbook/<playbook_id>/execute/

Webhook Trigger

POST /api/user/<user_id>/playbook/<playbook_id>/webhook/

Any JSON body is passed to the playbook as input_data.

Execution History

GET /api/user/<user_id>/playbook/<playbook_id>/histories/
GET /api/user/<user_id>/playbook/<playbook_id>/history/<history_id>/

Versions

GET /api/user/<user_id>/playbook/<playbook_id>/versions/
GET /api/user/<user_id>/playbook/<playbook_id>/version/<version_id>/

Environment Variables

GET /api/user/<user_id>/playbook/<playbook_id>/environments/
PUT /api/user/<user_id>/playbook/<playbook_id>/environments/
DELETE /api/user/<user_id>/playbook/<playbook_id>/environments/
GET /api/user/<user_id>/playbook/<playbook_id>/environment/<key>/

Merge

POST /api/user/<user_id>/playbook/<playbook_id>/merge/<target_id>/

Autotest

GET /api/user/<user_id>/playbook/<playbook_id>/autotest/
PUT /api/user/<user_id>/playbook/<playbook_id>/autotest/
POST /api/user/<user_id>/playbook/<playbook_id>/autotest/execute

Pipeline Endpoints

List Pipelines

GET /api/user/<user_id>/pipeline/

Create Pipeline

POST /api/user/<user_id>/pipeline/

Body:

Field Type Required Description
name string Yes Pipeline name (unique within the org)
druid_parse string No Regex pattern with numbered capture groups
druid_parse_field string No Comma-separated field names; a name may include a type as name(Type) (e.g. dst_port(Int32)), defaulting to String
druid_ttl integer No Retention in days (0 = unlimited)
is_active boolean No Active status

Parse modes

If druid_parse is empty, the pipeline treats messages as JSON and extracts fields at query time (invalid JSON yields NULL). If druid_parse is set, it runs in regex mode. Either way, extraction happens at query time (schema-on-read). In both modes a field name in druid_parse_field may carry a type as name(Type) (e.g. dst_port(Int32)); untyped names default to String, and a value that does not match its type becomes NULL.

Example:

{
  "name": "apache-access",
  "druid_parse": "(\\S+) \\S+ \\S+ \\[([^\\]]+)\\] \"(\\S+) (\\S+) \\S+\" (\\d+) (\\d+)",
  "druid_parse_field": "remote_host, timestamp, method, path, status, bytes",
  "druid_ttl": 90,
  "is_active": true
}

Get Pipeline

GET /api/user/<user_id>/pipeline/<pipeline_id>/

Update Pipeline

PUT /api/user/<user_id>/pipeline/<pipeline_id>/

Delete Pipeline

DELETE /api/user/<user_id>/pipeline/<pipeline_id>/

AI Parse Generation

POST /api/user/<user_id>/generate-parse/

Generates a regex and field names from a sample log. The output is a suggestion for the user to review and apply; field names are normalized toward the ECS schema.

Body:

{
  "sample_log": "192.168.1.100 - - [15/Jan/2025:10:30:00 +0900] \"GET /api/users HTTP/1.1\" 200 1234"
}

Pipeline Sharing

POST /api/user/<user_id>/share/pipeline/
DELETE /api/user/<user_id>/share/pipeline/
GET /api/user/<user_id>/share/list/
GET /api/user/<user_id>/shared-case-domains/

UEBA Endpoints

Get UEBA Configuration

GET /api/user/<user_id>/UEBA/

Update UEBA Settings

PUT /api/user/<user_id>/UEBA/

Asset Management

GET /api/user/<user_id>/ueba/assets/
PUT /api/user/<user_id>/ueba/assets/<asset_id>/
DELETE /api/user/<user_id>/ueba/assets/<asset_id>/delete/

Task-Asset Linking

GET /api/user/<user_id>/ueba/tasks/<playbook_id>/assets/
POST /api/user/<user_id>/ueba/tasks/<playbook_id>/assets/link/
DELETE /api/user/<user_id>/ueba/tasks/<playbook_id>/assets/<asset_id>/
PUT /api/user/<user_id>/ueba/tasks/<playbook_id>/assets/sync/

Group Asset Management

GET /api/user/<user_id>/ueba/groups/<group_id>/assets/
PUT /api/user/<user_id>/ueba/groups/<group_id>/assets/sync/

UEBA Templates (Admin)

GET /api/ueba-templates/
POST /api/ueba-templates/
GET /api/ueba-templates/get_all_templates/
POST /api/ueba-templates/add_and_sync/

What UEBA is

UEBA here manages scheduled detection Playbook tasks. The detection logic lives in the referenced Playbooks. The platform does not ship a statistical baseline, ML anomaly-scoring, or geolocation-anomaly engine of its own.


Dashboard Endpoints

Dashboard CRUD

GET /api/user/<user_id>/dashboard/
POST /api/user/<user_id>/dashboard/
GET /api/user/<user_id>/dashboard/<dashboard_id>/
POST /api/user/<user_id>/dashboard/<dashboard_id>/

Create Body:

{
  "name": "Security Overview",
  "visualizations": [
    {
      "attributes": "viz-001",
      "layout": {"x": 0, "y": 0, "w": 6, "h": 4},
      "metadata": {}
    }
  ]
}

Visualization CRUD

GET /api/user/<user_id>/visualize/
POST /api/user/<user_id>/visualize/
GET /api/user/<user_id>/visualize/<viz_id>/
POST /api/user/<user_id>/visualize/<viz_id>/
DELETE /api/user/<user_id>/visualize/

Create Body:

{
  "title": "Top Blocked IPs",
  "query": "from `firewall_logs` filter action == \"DENY\" group {src_ip} (aggregate {count = count this}) sort {-count} take 10",
  "chartType": "bar",
  "timerange": "last 24 hours",
  "xAxisField": "src_ip",
  "yAxisField": "count"
}

Chart Types: timeline, bar, line, pie, doughnut, polarArea, radar, markdown, table

Grid Layout: 12-column system. {"x": 0, "y": 0, "w": 6, "h": 4}


Organization Endpoints

User Management

GET /api/user/profile/
GET /api/user/<user_id>/
POST /api/user/<user_id>/
PUT /api/user/<user_id>/
DELETE /api/user/<user_id>/
POST /api/users/multiple/

Organization

GET /api/user/<user_id>/organization/
POST /api/user/<user_id>/organization/
PUT /api/user/<user_id>/organization/
GET /api/user/<user_id>/organization/users/

Invitations

POST /api/user/<user_id>/invite/
POST /api/accept-invitation/<token>/

API Keys

GET /api/user/<user_id>/api-key/
POST /api/user/<user_id>/api-key/
GET /api/user/<user_id>/api-key/<key_id>/
DELETE /api/user/<user_id>/api-key/<key_id>/
DELETE /api/user/<user_id>/api-key/

Important

The key value is included only in the creation response. Store it securely. It cannot be retrieved later.

Throttle (Rate Limiting)

GET /api/user/<user_id>/organization/throttle/

Audit Logs

GET /api/user/<user_id>/organization/audit/search/

Query Parameters: query, dateFrom, dateTo, limit, offset

Escalation Policies

GET /api/user/<user_id>/escalation-policies/
POST /api/user/<user_id>/escalation-policies/
GET /api/user/<user_id>/escalation-policies/<policy_id>/
PUT /api/user/<user_id>/escalation-policies/<policy_id>/
POST /api/user/<user_id>/escalation-policies/<policy_id>/test/

Integration Endpoints

Available Integrations

GET /api/organizations/integrations/
GET /api/organizations/integrations/<uuid>/

Enabled Integrations

GET /api/organizations/enabled-integrations/
POST /api/organizations/enabled-integrations/

Enable Body:

{
  "integration_uuid": "int-uuid-001",
  "enabled": true
}

SharedAccess

GET /api/organizations/shared-access/
POST /api/organizations/shared-access/
GET /api/organizations/shared-access/<id>/
PUT /api/organizations/shared-access/<id>/
DELETE /api/organizations/shared-access/<id>/

Create Body:

{
  "resource_type": "pipeline",
  "resource_id": "pipe-001",
  "shared_with_organization": "org-uuid-002",
  "permission": "read",
  "permission_type": "log",
  "permission_query": "{\"severity\": \"high\"}"
}

Permission levels: read, write, admin

Permission types: log, case, playbook, pipeline, load_dashboard, asset


Chat Endpoints

Rooms

GET /api/chat/rooms/
POST /api/chat/rooms/
GET /api/chat/rooms/<room_id>/
PUT /api/chat/rooms/<room_id>/
DELETE /api/chat/rooms/<room_id>/
POST /api/chat/rooms/create_or_get/
GET /api/chat/rooms/get_by_target_organization/?org_id=<org-uuid>
GET /api/chat/rooms/list_by_organization/
POST /api/chat/rooms/<room_id>/mark_all_as_read/

Messages

GET /api/chat/messages/?room_id=<room_id>
POST /api/chat/messages/
GET /api/chat/messages/<message_id>/
PUT /api/chat/messages/<message_id>/
DELETE /api/chat/messages/<message_id>/
POST /api/chat/messages/mark_as_read/
GET /api/chat/messages/search/?q=<search_term>
GET /api/chat/messages/unread_count/
GET /api/chat/messages/updates/?since=<timestamp>

Files

GET /api/chat/files/?room_id=<room_id>
POST /api/chat/files/                     (multipart/form-data)
GET /api/chat/files/<file_id>/
GET /api/chat/files/<file_id>/download/
DELETE /api/chat/files/<file_id>/

OpenAPI Documentation

Interactive API documentation is available at the following URLs:

URL Description
/swagger/ Swagger UI
/swagger.json OpenAPI spec (JSON)
/swagger.yaml OpenAPI spec (YAML)
/redoc/ ReDoc UI