Skip to content

Intrudect Public API

This document describes the public Intrudect API intended for customer integrations and scripting.

API keys for this API are created in the Intrudect Web UI under User->API Keys. They are separate from portal API keys used for license signing.

Private endpoints used by Intrudect agents and internal components, such as /api/agent, /api/log, and /api/alert, are not part of this public API reference.

Base URL

Public API endpoints are versioned under:

/api/v1

Example endpoint URL using the shell variable:

${INTRUDECT_BASE_URL}/api/v1/devices

For copy-paste friendly examples, set these shell variables first:

export INTRUDECT_BASE_URL="https://intrudect.example.com"
export INTRUDECT_API_TOKEN="your-api-token"

Authentication

Public API requests use bearer-token authentication:

Authorization: Bearer <api-token>

API tokens are separate from agent tokens and web session cookies. Obtain an API token from your Intrudect administrator.

Permissions

API tokens are tied to Intrudect users and use the same permission model as the web UI.

API Function Required Permission
Read about/system information Valid API token only; no additional permission
Read/search devices Devices read permission (perm_devices_r)
Update devices Devices write permission (perm_devices_w)
Read/search networks Networks read permission (perm_networks_r)
Create/update/delete networks Networks write permission (perm_networks_w)
Read/search network alerts Alerts read permission (perm_alerts_r)
Delete network alerts Alerts write permission (perm_alerts_w)
Read/search server alerts Alerts read permission (perm_alerts_r)
Delete server alerts Alerts write permission (perm_alerts_w)
Export data-management datasets Data read permission (perm_data_r)
Delete data-management rows Data write permission (perm_data_w)
Read/search services Devices read permission (perm_devices_r)
Create/update/delete/authorize services Devices write permission (perm_devices_w)

Permission failures for endpoints with required permissions return HTTP status 403 with the standard error object.

Errors

Errors are returned as JSON objects:

{"error":"message"}

The error value is a short diagnostic message. Clients should primarily handle HTTP status codes; exact messages can vary by endpoint and validation path.

Common status categories:

Status Meaning
400 Invalid path parameter, query parameter, JSON body, filter, date, or request value.
401 Missing or invalid bearer token.
403 The token's user lacks the required permission.
404 The requested row does not exist.
409 The request conflicts with existing data.
500 Internal service or database error.

Not every status applies to every endpoint.

Pagination

Device, network alert, and server alert list and search endpoints return pagination metadata:

{
  "page": 1,
  "page_size": 100,
  "total_rows": 125,
  "total_pages": 2
}

Defaults and limits:

Parameter Default Limit
page 1 Values below 1 are treated as 1.
page_size 100 Values above 1000 are clamped to 1000.

If page is greater than the last page, the API returns the last available page.

About

Get About Information

GET /api/v1/about

Returns the same fast system and database information that the web /settings/about page displays immediately. Requires a valid API bearer token, but no additional user permission.

This endpoint does not run exact COUNT(*) queries on large tables. Record counts are fast estimates from information_schema.TABLES.table_rows, and each count includes "row_count_is_estimate": true. Size values are raw byte counts so API clients do not have to parse web display strings.

Example:

curl -s \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/about"

Response:

{
  "version": "1.2.3",
  "runtime_memory_bytes": 12582912,
  "database": {
    "size_bytes": 987654321,
    "network_alerts": {
      "row_count": 1200,
      "row_count_is_estimate": true
    },
    "tcp_records": {
      "row_count": 550000,
      "row_count_is_estimate": true,
      "size_bytes": 345678901,
      "first_record_at": "2026-06-01 00:00:00",
      "last_record_at": "2026-06-06 10:30:00"
    },
    "dns_records": {
      "row_count": 780000,
      "row_count_is_estimate": true,
      "size_bytes": 234567890,
      "first_record_at": "2026-06-01 00:00:00",
      "last_record_at": "2026-06-06 10:30:00"
    },
    "dhcp_records": {
      "row_count": 4500,
      "row_count_is_estimate": true,
      "size_bytes": 1234567,
      "first_record_at": "2026-06-01 00:10:00",
      "last_record_at": "2026-06-06 09:55:00"
    },
    "http_records": {
      "row_count": 23000,
      "row_count_is_estimate": true,
      "size_bytes": 3456789,
      "first_record_at": "2026-06-01 00:15:00",
      "last_record_at": "2026-06-06 09:45:00"
    },
    "tor_relays": {
      "last_updated_at": "2026-06-06",
      "size_bytes": 456789
    },
    "misp_ip_records": {
      "last_updated_at": "2026-06-06 06:00:00",
      "size_bytes": 567890
    },
    "misp_dns_records": {
      "last_updated_at": "2026-06-06 06:00:00",
      "size_bytes": 678901
    }
  },
  "schema_health": {
    "is_healthy": true,
    "tables": [
      {
        "name": "users",
        "missing_indexes": [],
        "extra_indexes": [],
        "wrong_index_cols": [],
        "is_healthy": true
      }
    ]
  }
}

Device Object

Device responses use this JSON shape:

{
  "id": 123,
  "mac": "AA:BB:CC:DD:EE:FF",
  "last_ip": "10.0.0.25",
  "hostname": "workstation-01",
  "friendly_name": "Alice Laptop",
  "vendor": "Example Networks",
  "network": "Office LAN",
  "is_gateway": false,
  "first_seen": "2026-06-01 09:15:00",
  "last_seen": "2026-06-03 10:30:00"
}

first_seen and last_seen are returned in the Intrudect server's configured timezone using YYYY-MM-DD HH:MM:SS format.

is_gateway is true when last_ip matches a configured gateway_ip in the networks table. Gateway MAC values are not used for this marker because routed traffic can show many remote IPs with the router MAC.

Network Object

Network responses use this JSON shape:

{
  "id": 42,
  "name": "Office LAN",
  "cidr": "10.0.0.0/24",
  "gateway_ip": "10.0.0.1",
  "gateway_mac": "AA:BB:CC:DD:EE:FF",
  "alert": 20
}

alert is the new-device alert level for the network. Supported values are 0, 10, 20, and 30.

gateway_ip and gateway_mac are optional. Empty values are returned as empty strings. Non-empty gateway_mac values are normalized to uppercase colon-separated form.

Service Object

Service list and search responses are grouped by service IP:

{
  "service_ip": "10.0.0.25",
  "name": "Web Server",
  "authorized": false,
  "first_seen": "2026-06-01 09:15:00",
  "last_seen": "2026-06-03 10:30:00",
  "tcp_ports": [
    {
      "id": 1001,
      "port": 443,
      "proto": "tcp",
      "authorized": false,
      "first_seen": "2026-06-01 09:15:00",
      "last_seen": "2026-06-03 10:30:00"
    }
  ],
  "udp_ports": []
}

Create, update, delete, and authorize-by-ID responses return a single service row:

{
  "id": 1001,
  "service_ip": "10.0.0.25",
  "service_port": 443,
  "proto": "tcp",
  "name": "Web Server",
  "authorized": false,
  "first_seen": "2026-06-01 09:15:00",
  "last_seen": "2026-06-03 10:30:00"
}

first_seen and last_seen are returned in the Intrudect server's configured timezone using YYYY-MM-DD HH:MM:SS format. Request timestamps use the same format and are interpreted in the configured timezone.

Network Alert Object

Network alert responses use this JSON shape:

{
  "id": 12345,
  "timestamp": "2026-06-03 10:30:00",
  "agent": "agent-hash",
  "agent_name": "Office sensor",
  "src_mac": "AA:BB:CC:DD:EE:FF",
  "dst_mac": "11:22:33:44:55:66",
  "src_ip": "10.0.0.25",
  "dst_ip": "10.0.0.50",
  "src_port": 53000,
  "dst_port": 3389,
  "src_hostname": "workstation-01",
  "dst_hostname": "server-01",
  "level": 30,
  "type": "portscan",
  "subject": "Port scan detected",
  "message": "Example alert message",
  "pcap_id": 987,
  "src_device_name": "Alice Laptop",
  "dst_device_name": "RDP Server",
  "src_network_name": "Office LAN",
  "dst_network_name": "Server LAN",
  "is_src_public_ip": false,
  "is_dst_public_ip": false
}

timestamp is returned in the Intrudect server's configured timezone using YYYY-MM-DD HH:MM:SS format. Request date filters use YYYY-MM-DD HH:MM and are interpreted in the configured timezone.

Server Alert Object

Server alert responses use this JSON shape:

{
  "id": 12345,
  "timestamp": "2026-06-03 10:30:00",
  "agent": "agent-hash",
  "agent_name": "Syslog sensor",
  "hostname": "server-01",
  "level": 20,
  "type": "auth",
  "title": "Failed password",
  "line": "sshd[100]: Failed password for root from 10.0.0.25"
}

title is the syslogalerts.message column shown as the web UI's Title/Type selector. line is the full log message. timestamp is returned in the Intrudect server's configured timezone using YYYY-MM-DD HH:MM:SS format. Request date filters use YYYY-MM-DD HH:MM and are interpreted in the configured timezone.

Devices

Device Sorting

Device list and search endpoints support sorting. GET /api/v1/devices uses sort and order query parameters. POST /api/v1/devices/search uses sort.field and sort.order in the JSON body.

Default sort is last_ip; default order is asc. Invalid sort fields fall back to last_ip; invalid order values fall back to asc.

Field Meaning
last_ip, lastip, ip Last observed IP address
hostname Device hostname
friendly_name, name User-defined friendly name
mac MAC address
vendor MAC vendor name
gateway, is_gateway Whether the device IP is configured as a network gateway IP
ipcount, ip_count, ip_history Number of observed IP addresses for the device
first_seen, first First observed timestamp
last_seen, last Last observed timestamp

List Devices

GET /api/v1/devices

Lists devices with pagination and sorting. Filtering is not supported on this endpoint; use POST /api/v1/devices/search for filtered device searches.

Query parameters:

Parameter Type Description
page integer Page number.
page_size integer Rows per page.
sort string Sort field.
order string asc or desc.

If any filter parameter such as ip, mac, vendor, hostname, or friendly_name is supplied to this endpoint, the API returns 400.

Example:

curl -s \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/devices?page=1&page_size=25&sort=hostname&order=asc"

Response:

{
  "devices": [
    {
      "id": 123,
      "mac": "AA:BB:CC:DD:EE:FF",
      "last_ip": "10.0.0.25",
      "hostname": "workstation-01",
      "friendly_name": "Alice Laptop",
      "vendor": "Example Networks",
      "network": "Office LAN",
      "is_gateway": false,
      "first_seen": "2026-06-01 09:15:00",
      "last_seen": "2026-06-03 10:30:00"
    }
  ],
  "page": 1,
  "page_size": 25,
  "total_rows": 1,
  "total_pages": 1
}

Search Devices

POST /api/v1/devices/search

Searches devices using a structured JSON request. Use this endpoint for scripts that need array filters.

Request body:

{
  "filters": {
    "mac": ["AA:BB:CC:DD:EE:FF"],
    "ip": ["10.0.0.25"],
    "vendor": ["Example Networks"],
    "hostname": ["workstation-01"],
    "friendly_name": ["Alice Laptop"]
  },
  "page": 1,
  "page_size": 25,
  "sort": {
    "field": "last_seen",
    "order": "desc"
  }
}

All fields are optional. Use {} for an unfiltered search with defaults.

Filter behavior:

Filter Behavior
Multiple values in one array Match any value in that filter.
Multiple filter fields Match all supplied filter fields.
% or _ in a filter value Treated as SQL wildcard pattern characters.
Comma-separated strings Not supported as public API array syntax; send JSON arrays instead.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"ip":["10.0.0.25"],"friendly_name":["Alice Laptop"]},"page":1,"page_size":25}' \
  "${INTRUDECT_BASE_URL}/api/v1/devices/search"

Response shape is the same as GET /api/v1/devices.

Update Device

PATCH /api/v1/devices/{id}
PUT /api/v1/devices/{id}

Updates the editable device fields. PATCH and PUT currently have the same behavior.

Path parameters:

Parameter Type Description
id integer Device ID.

Request body:

{
  "hostname": "workstation-01",
  "friendly_name": "Alice Laptop"
}

Both fields are optional individually. At least one field must be supplied, and the resulting device must have either hostname or friendly_name set.

Example:

curl -s \
  -X PATCH \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"friendly_name":"Alice Laptop"}' \
  "${INTRUDECT_BASE_URL}/api/v1/devices/123"

Response:

{
  "device": {
    "id": 123,
    "mac": "AA:BB:CC:DD:EE:FF",
    "last_ip": "10.0.0.25",
    "hostname": "workstation-01",
    "friendly_name": "Alice Laptop",
    "vendor": "Example Networks",
    "network": "Office LAN",
    "first_seen": "2026-06-01 09:15:00",
    "last_seen": "2026-06-03 10:30:00"
  }
}

Networks

Network Sorting

Network list and search endpoints support sorting. GET /api/v1/networks uses sort and order query parameters. POST /api/v1/networks/search uses sort.field and sort.order in the JSON body.

Network endpoints are not paginated. Default sort is name; default order is asc. Invalid sort fields fall back to name; invalid order values fall back to asc.

Field Meaning
id Network ID
name Network name
cidr CIDR block
gateway_ip Optional gateway IP address
gateway_mac Optional gateway MAC address
alert New-device alert level

List Networks

GET /api/v1/networks

Lists networks with sorting. Filtering is not supported on this endpoint; use POST /api/v1/networks/search for filtered network searches.

Query parameters:

Parameter Type Description
sort string Sort field.
order string asc or desc.

If any filter parameter such as name, cidr, gateway_ip, gateway_mac, or alert is supplied to this endpoint, the API returns 400.

Example:

curl -s \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/networks?sort=name&order=asc"

Response:

{
  "networks": [
    {
      "id": 42,
      "name": "Office LAN",
      "cidr": "10.0.0.0/24",
      "gateway_ip": "10.0.0.1",
      "gateway_mac": "AA:BB:CC:DD:EE:FF",
      "alert": 20
    }
  ]
}

Search Networks

POST /api/v1/networks/search

Searches networks using a structured JSON request.

Request body:

{
  "filters": {
    "name": ["Office LAN"],
    "cidr": ["10.0.0.0/24"],
    "gateway_ip": ["10.0.0.1"],
    "gateway_mac": ["AA:BB:CC:DD:EE:FF"],
    "alert": [20]
  },
  "sort": {
    "field": "name",
    "order": "asc"
  }
}

All fields are optional. Use {} for an unfiltered search with defaults.

Filter behavior:

Filter Behavior
Multiple values in one array Match any value in that filter.
Multiple filter fields Match all supplied filter fields.
% or _ in name, cidr, gateway_ip, or gateway_mac Treated as SQL wildcard pattern characters.
alert Matches exact alert levels.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"name":["Office%"],"alert":[20]},"sort":{"field":"cidr","order":"asc"}}' \
  "${INTRUDECT_BASE_URL}/api/v1/networks/search"

Response shape is the same as GET /api/v1/networks.

Create Network

POST /api/v1/networks

Creates a network.

Request body:

{
  "name": "Office LAN",
  "cidr": "10.0.0.0/24",
  "gateway_ip": "10.0.0.1",
  "gateway_mac": "AA:BB:CC:DD:EE:FF",
  "alert": 20
}

name and cidr are required. gateway_ip and gateway_mac are optional. alert defaults to 0 when omitted.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"name":"Office LAN","cidr":"10.0.0.0/24","gateway_ip":"10.0.0.1","gateway_mac":"AA:BB:CC:DD:EE:FF","alert":20}' \
  "${INTRUDECT_BASE_URL}/api/v1/networks"

Response status is 201:

{
  "network": {
    "id": 42,
    "name": "Office LAN",
    "cidr": "10.0.0.0/24",
    "gateway_ip": "10.0.0.1",
    "gateway_mac": "AA:BB:CC:DD:EE:FF",
    "alert": 20
  }
}

Update Network

PATCH /api/v1/networks/{id}
PUT /api/v1/networks/{id}

Updates a network. PATCH and PUT currently have the same behavior.

Path parameters:

Parameter Type Description
id integer Network ID.

Request body:

{
  "name": "Office LAN",
  "cidr": "10.0.0.0/24",
  "gateway_ip": "10.0.0.1",
  "gateway_mac": "AA:BB:CC:DD:EE:FF",
  "alert": 20
}

All fields are optional individually. At least one field must be supplied, and the resulting network must still have a non-empty name, valid cidr, and valid gateway values when gateway fields are non-empty.

Example:

curl -s \
  -X PATCH \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"alert":30}' \
  "${INTRUDECT_BASE_URL}/api/v1/networks/42"

Response:

{
  "network": {
    "id": 42,
    "name": "Office LAN",
    "cidr": "10.0.0.0/24",
    "gateway_ip": "10.0.0.1",
    "gateway_mac": "AA:BB:CC:DD:EE:FF",
    "alert": 30
  }
}

Delete Network

DELETE /api/v1/networks/{id}

Deletes a network and related network policy rows.

Path parameters:

Parameter Type Description
id integer Network ID.

Example:

curl -s \
  -X DELETE \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/networks/42"

Response:

{
  "deleted": true,
  "network": {
    "id": 42,
    "name": "Office LAN",
    "cidr": "10.0.0.0/24",
    "gateway_ip": "10.0.0.1",
    "gateway_mac": "AA:BB:CC:DD:EE:FF",
    "alert": 30
  }
}

Network Alerts

Network Alert Sorting

Network alert list and search endpoints support sorting. GET /api/v1/networkalerts uses sort and order query parameters. POST /api/v1/networkalerts/search uses sort.field and sort.order in the JSON body.

Default sort is timestamp; default order is desc. Invalid sort fields fall back to timestamp; invalid order values fall back to desc.

Field Meaning
id Alert row ID
timestamp, first Alert timestamp
agent Agent hash
source Source IP and MAC
destination Destination IP and MAC
src_ip Source IP
dst_ip Destination IP
dst_port Destination port
type Alert type
level Alert level
subject Alert subject
message Alert message

List Network Alerts

GET /api/v1/networkalerts

Lists network alerts with pagination and sorting. Filtering is not supported on this endpoint; use POST /api/v1/networkalerts/search for filtered network alert searches.

Query parameters:

Parameter Type Description
page integer Page number.
page_size integer Rows per page.
sort string Sort field.
order string asc or desc.

If any filter parameter such as from, to, source, destination, type, level, or search is supplied to this endpoint, the API returns 400.

Example:

curl -s \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/networkalerts?page=1&page_size=25&sort=timestamp&order=desc"

Response:

{
  "network_alerts": [
    {
      "id": 12345,
      "timestamp": "2026-06-03 10:30:00",
      "agent": "agent-hash",
      "agent_name": "Office sensor",
      "src_ip": "10.0.0.25",
      "dst_ip": "10.0.0.50",
      "src_port": 53000,
      "dst_port": 3389,
      "level": 30,
      "type": "portscan",
      "subject": "Port scan detected",
      "message": "Example alert message",
      "pcap_id": 987
    }
  ],
  "page": 1,
  "page_size": 25,
  "total_rows": 1,
  "total_pages": 1
}

Search Network Alerts

POST /api/v1/networkalerts/search

Searches network alerts using a structured JSON request.

Request body:

{
  "filters": {
    "from": "2026-06-03 00:00",
    "to": "2026-06-04 00:00",
    "agent": ["agent-hash"],
    "level": [30],
    "type": ["portscan"],
    "type_mode": 1,
    "source": ["10.0.0.25"],
    "destination": ["10.0.0.50"],
    "destination_port": [3389],
    "search": ["Port scan"],
    "unique": "pair"
  },
  "page": 1,
  "page_size": 25,
  "sort": {
    "field": "timestamp",
    "order": "desc"
  }
}

All fields are optional. Use {} for an unfiltered search with defaults.

Filter behavior:

Filter Behavior
from, to Inclusive timestamp bounds in YYYY-MM-DD HH:MM format.
agent or agent_id Matches agent hashes.
level Matches exact alert levels such as 10, 20, or 30.
type Matches alert type strings.
type_mode 1 means only selected types; 2 means exclude selected types. Defaults to 1.
source Matches source IP or source MAC. Hostnames/device names are resolved the same way as the web UI. % and _ are SQL wildcards.
destination Matches destination IP or destination MAC. Hostnames/device names are resolved the same way as the web UI. % and _ are SQL wildcards.
destination_port or dst_port Matches exact destination ports.
search Searches destination IP, subject, message, and destination:port.
unique Collapse results by source, destination, destinationport, or pair; the newest row ID per group is returned.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"level":[30],"source":["10.0.0.25"],"type":["portscan"]},"page":1,"page_size":25}' \
  "${INTRUDECT_BASE_URL}/api/v1/networkalerts/search"

Response shape is the same as GET /api/v1/networkalerts.

Delete Network Alert

DELETE /api/v1/networkalerts/{id}

Deletes one network alert by ID. If the alert has a PCAP row, that PCAP row is deleted in the same transaction. Network alert PCAP rows are treated as one-to-one alert-owned data.

Path parameters:

Parameter Type Description
id integer Network alert ID.

Example:

curl -s \
  -X DELETE \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/networkalerts/12345"

Response:

{
  "deleted": true,
  "network_alert": {
    "id": 12345,
    "timestamp": "2026-06-03 10:30:00",
    "agent": "agent-hash",
    "agent_name": "Office sensor",
    "src_ip": "10.0.0.25",
    "dst_ip": "10.0.0.50",
    "src_port": 53000,
    "dst_port": 3389,
    "level": 30,
    "type": "portscan",
    "subject": "Port scan detected",
    "message": "Example alert message",
    "pcap_id": 987
  }
}

Server Alerts

Server Alert Sorting

Server alert list and search endpoints support sorting. GET /api/v1/serveralerts uses sort and order query parameters. POST /api/v1/serveralerts/search uses sort.field and sort.order in the JSON body.

Default sort is timestamp; default order is desc. Invalid sort fields fall back to timestamp; invalid order values fall back to desc.

Field Meaning
id Alert row ID
timestamp Alert timestamp
source, hostname Source hostname
agent Agent hash
type Syslog alert type
title, subject, message Alert title
level Alert level
log, line Full log line

List Server Alerts

GET /api/v1/serveralerts

Lists server/syslog alerts with pagination and sorting. Filtering is not supported on this endpoint; use POST /api/v1/serveralerts/search for filtered server alert searches.

Query parameters:

Parameter Type Description
page integer Page number.
page_size integer Rows per page.
sort string Sort field.
order string asc or desc.

If any filter parameter such as from, to, agent, hostname, type, title, level, or search is supplied to this endpoint, the API returns 400.

Example:

curl -s \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/serveralerts?page=1&page_size=25&sort=timestamp&order=desc"

Response:

{
  "server_alerts": [
    {
      "id": 12345,
      "timestamp": "2026-06-03 10:30:00",
      "agent": "agent-hash",
      "agent_name": "Syslog sensor",
      "hostname": "server-01",
      "level": 20,
      "type": "auth",
      "title": "Failed password",
      "line": "sshd[100]: Failed password for root from 10.0.0.25"
    }
  ],
  "page": 1,
  "page_size": 25,
  "total_rows": 1,
  "total_pages": 1
}

Search Server Alerts

POST /api/v1/serveralerts/search

Searches server/syslog alerts using a structured JSON request.

Request body:

{
  "filters": {
    "from": "2026-06-03 00:00",
    "to": "2026-06-04 00:00",
    "agent": ["agent-hash"],
    "hostname": ["server-01"],
    "level": [20],
    "type": ["auth"],
    "title": ["Failed password"],
    "search": ["root from 10.0.0.25"]
  },
  "page": 1,
  "page_size": 25,
  "sort": {
    "field": "timestamp",
    "order": "desc"
  }
}

All fields are optional. Use {} for an unfiltered search with defaults.

Filter behavior:

Filter Behavior
from, to Inclusive timestamp bounds in YYYY-MM-DD HH:MM format.
agent or agent_id Matches agent hashes.
hostname Matches source hostnames. % and _ are SQL wildcards.
level Matches exact alert levels such as 10, 20, or 30.
type Matches the syslogalerts.type value.
title or message Matches the alert title (syslogalerts.message). The comparison uses LIKE, matching the web UI type selector behavior.
search or line Searches the full log line (syslogalerts.line) with contains semantics.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"level":[20],"type":["auth"],"search":["Failed password"]},"page":1,"page_size":25}' \
  "${INTRUDECT_BASE_URL}/api/v1/serveralerts/search"

Response shape is the same as GET /api/v1/serveralerts.

Delete Server Alert

DELETE /api/v1/serveralerts/{id}

Deletes one server/syslog alert by ID.

Path parameters:

Parameter Type Description
id integer Server alert ID.

Example:

curl -s \
  -X DELETE \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/serveralerts/12345"

Response:

{
  "deleted": true,
  "server_alert": {
    "id": 12345,
    "timestamp": "2026-06-03 10:30:00",
    "agent": "agent-hash",
    "agent_name": "Syslog sensor",
    "hostname": "server-01",
    "level": 20,
    "type": "auth",
    "title": "Failed password",
    "line": "sshd[100]: Failed password for root from 10.0.0.25"
  }
}

Data Management

Data-management endpoints use the same dataset keys and filters as the web UI. Date filters accept YYYY-MM-DD, YYYY-MM-DD HH:MM, or YYYY-MM-DD HH:MM:SS and are interpreted in the Intrudect server's configured timezone. A date-only to value includes the full day.

Dataset keys:

Key Dataset Export ZIP entry
network_alerts Network alerts networkalerts.csv
syslog_alerts Server/syslog alerts syslogalerts.csv
dns_metadata DNS log metadata metadata_dns.csv
tcp_metadata TCP/netflow metadata metadata_connections.csv
dhcp_metadata DHCP metadata dhcpflow.csv
http_metadata HTTP metadata httpflow.csv

Common filters:

Filter Type Description
from string Inclusive lower timestamp bound.
to string Inclusive upper timestamp bound.
agent_id or agent string Agent hash. Omit or use all for all agents.

Table-specific filters are nested under the dataset key in the request filters object:

Dataset Filters
network_alerts source, destination, destination_port or dst_port, level, type, alert_type, search
syslog_alerts hostname, level, search, message, line
dns_metadata source, destination, qtype, query
tcp_metadata source, destination, source_port or src_port, destination_port or dst_port, geoip
dhcp_metadata mac, hostname, ip
http_metadata source, destination, source_port or src_port, destination_port or dst_port, host, uri, user_agent

The API also accepts the web form field names such as na_srcip, sl_search, dns_query, tcp_dport, and http_useragent inside filters for scripts that mirror web submissions.

Export Data

POST /api/v1/data/export

Exports one or more datasets as a ZIP file containing CSV files. Requires data read permission (perm_data_r).

Request body:

{
  "datasets": ["network_alerts", "syslog_alerts"],
  "filters": {
    "from": "2026-06-03 00:00",
    "to": "2026-06-04 00:00",
    "agent_id": "agent-hash",
    "network_alerts": {
      "search": "malware",
      "level": "30"
    },
    "syslog_alerts": {
      "search": "Failed password"
    }
  }
}

tables may be used instead of datasets. table may be used for a single-dataset export.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"datasets":["dns_metadata"],"filters":{"from":"2026-06-03","dns_metadata":{"query":"%.example.com"}}}' \
  -o intrudect-export.zip \
  "${INTRUDECT_BASE_URL}/api/v1/data/export"

Export response:

Status Content-Type Body
200 application/zip ZIP archive containing one CSV per requested dataset.

Delete Data

POST /api/v1/data/delete

Deletes rows from one dataset using the same filter model as export. Requires data write permission (perm_data_w). Network-alert deletes also delete the owned PCAP rows referenced by networkalerts.pcap. DNS and TCP deletes rebuild their 15-minute aggregate tables after deleting raw rows.

Request body:

{
  "table": "network_alerts",
  "filters": {
    "from": "2026-06-03 00:00",
    "to": "2026-06-04 00:00",
    "network_alerts": {
      "source": "10.0.0.%",
      "destination_port": "443",
      "level": "30"
    }
  }
}

Response:

{
  "table": "network_alerts",
  "label": "network alerts",
  "deleted_rows": 12,
  "network_pcaps_deleted": true
}

DNS delete response includes "dns_aggregates_rebuilt": true. TCP delete response includes "tcp_aggregates_rebuilt": true.

Services

Service Sorting

Service list and search endpoints support sorting. GET /api/v1/services uses sort and order query parameters. POST /api/v1/services/search uses sort.field and sort.order in the JSON body.

Service endpoints are not paginated. Default sort is service_ip; default order is asc. Invalid sort fields fall back to service_ip; invalid order values fall back to asc.

Field Meaning
id Service row ID
service_ip, ip Service IP address
proto, protocol Protocol (tcp or udp)
service_port, port Service port
first_seen, first First observed timestamp
last_seen, last Last observed timestamp

List Services

GET /api/v1/services

Lists discovered services with sorting. Filtering is not supported on this endpoint; use POST /api/v1/services/search for filtered service searches.

Query parameters:

Parameter Type Description
sort string Sort field.
order string asc or desc.

If any filter parameter such as service_ip, ip, proto, service_port, port, or authorized is supplied to this endpoint, the API returns 400.

Example:

curl -s \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  "${INTRUDECT_BASE_URL}/api/v1/services?sort=service_ip&order=asc"

Response:

{
  "services": [
    {
      "service_ip": "10.0.0.25",
      "name": "Web Server",
      "authorized": false,
      "first_seen": "2026-06-01 09:15:00",
      "last_seen": "2026-06-03 10:30:00",
      "tcp_ports": [
        {
          "id": 1001,
          "port": 443,
          "proto": "tcp",
          "authorized": false,
          "first_seen": "2026-06-01 09:15:00",
          "last_seen": "2026-06-03 10:30:00"
        }
      ],
      "udp_ports": []
    }
  ]
}

Search Services

POST /api/v1/services/search

Searches discovered services using a structured JSON request. Responses are grouped by service IP and are not paginated.

Request body:

{
  "filters": {
    "service_ip": ["10.0.0.25"],
    "proto": ["tcp"],
    "service_port": [443],
    "authorized": [false]
  },
  "sort": {
    "field": "last_seen",
    "order": "desc"
  }
}

All fields are optional. ip is accepted as an alias for service_ip, and port is accepted as an alias for service_port.

Filter behavior:

Filter Behavior
Multiple values in one array Match any value in that filter.
Multiple filter fields Match all supplied filter fields.
% or _ in service_ip Treated as SQL wildcard pattern characters.
proto Matches exact protocol after lowercasing.
authorized Matches service ports after applying allowed-service and exclude-rule config.

Example:

curl -s \
  -X POST \
  -H "Authorization: Bearer ${INTRUDECT_API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"service_ip":["10.0.0.%"],"proto":["tcp"],"authorized":[false]}}' \
  "${INTRUDECT_BASE_URL}/api/v1/services/search"

Response shape is the same as GET /api/v1/services.

Create Service

POST /api/v1/services

Creates a discovered service row.

Request body:

{
  "service_ip": "10.0.0.25",
  "service_port": 443,
  "proto": "tcp",
  "first_seen": "2026-06-01 09:15:00",
  "last_seen": "2026-06-03 10:30:00"
}

service_ip, service_port, and proto are required. first_seen and last_seen are optional and default to the current time when omitted.

Response status is 201:

{
  "service": {
    "id": 1001,
    "service_ip": "10.0.0.25",
    "service_port": 443,
    "proto": "tcp",
    "name": "Web Server",
    "authorized": false,
    "first_seen": "2026-06-01 09:15:00",
    "last_seen": "2026-06-03 10:30:00"
  }
}

Update Service

PATCH /api/v1/services/{id}
PUT /api/v1/services/{id}

Updates a discovered service row. PATCH and PUT currently have the same behavior.

Request body:

{
  "service_ip": "10.0.0.26",
  "service_port": 8443,
  "proto": "tcp",
  "last_seen": "2026-06-03 10:30:00"
}

All fields are optional individually, but at least one field must be supplied.

Delete Service

DELETE /api/v1/services/{id}

Deletes a discovered service row.

Response:

{
  "deleted": true,
  "service": {
    "id": 1001,
    "service_ip": "10.0.0.25",
    "service_port": 443,
    "proto": "tcp",
    "name": "Web Server",
    "authorized": false,
    "first_seen": "2026-06-01 09:15:00",
    "last_seen": "2026-06-03 10:30:00"
  }
}

Authorize Service

PATCH /api/v1/services/{id}/authorize
POST /api/v1/services/authorize

Authorizes a service port by adding it to the network agent service-discovery allowed-services config. The PATCH endpoint authorizes an existing discovered service by ID. The POST endpoint authorizes by fields and does not require a discovered service row to already exist.

Field-based request body:

{
  "service_ip": "10.0.0.25",
  "service_port": 443,
  "proto": "tcp"
}