Operating

API Reference

CoreDetection exposes a REST API to monitor and manage the appliance entirely without a GUI. Every endpoint below lists its parameters and an example response. Paths are relative to the base URL.

Base URL

http://<server>:9009/CoreDetection/api/v0

The port (api_port) and base path (api_base_path) are set in the [api_settings] section of config.ini.

Authentication

Every endpoint except /health requires an API key, sent as a header or query parameter:

# header (recommended)
curl -H "X-API-Key: YOUR_KEY" \
  http://localhost:9009/CoreDetection/api/v0/status

# or query parameter
curl "http://localhost:9009/CoreDetection/api/v0/status?key=YOUR_KEY"

When api_rate_limit is set in [api_settings], exceeded requests return 429 Too Many Requests with a Retry-After: 60 header.

Endpoints

Health & Status

GET /health

Liveness/health check. The only endpoint that does NOT require authentication.

Example response
{
  "status": "ok",
  "uptime": "3m44s",
  "version": "1.0.263",
  "timestamp": "2026-06-03T02:30:25+03:00",
  "components": [
    { "name": "database", "status": "ok" },
    { "name": "bgp", "status": "ok" },
    { "name": "disk", "status": "ok", "message": "usage: 37.8%" },
    { "name": "memory", "status": "ok", "message": "usage: 16.5%" }
  ]
}
GET /status

Runtime summary: uptime, detection window, thresholds and database connection.

Example response
{
  "success": true,
  "status": {
    "uptime": "2m46s",
    "current_time": "2026-06-03T02:29:27+03:00",
    "detection_window": "1 minutes",
    "check_interval": "60 seconds",
    "min_detection_threshold": "400.00 Mbps",
    "database_connection": "localhost:9000"
  }
}

Live Attacks

GET /attacks/active

Attacks currently ongoing in memory (real-time state, not the log file).

Parameters
severity query string — Filter by severity: LOW | MEDIUM | HIGH | CRITICAL.
target query string — Filter by destination IP.
Example response
{
  "status": "success",
  "count": 1,
  "summary": {
    "active_total": 1,
    "by_severity": { "HIGH": 1 },
    "peak_gbps": 3.2,
    "peak_target": "185.10.20.5"
  },
  "attacks": [
    {
      "attack_id": "a1b2c3d4e5f6a7b8",
      "target": "185.10.20.5",
      "severity": "HIGH",
      "attack_type": "SYN Flood",
      "gbps": 3.2,
      "pps": 120000,
      "duration_seconds": 240,
      "status": "ONGOING"
    }
  ]
}

Reporting

GET /reports/attacks

Historical attack report read from the local JSONL log (no database required).

Parameters
limit query int — Max events to return (most recent first).
target query string — Filter by destination IP.
severity query string — Filter by severity level.
event query string — Filter by lifecycle event: START | UPDATE | REVIVE | END.
since query string — ISO-8601 start time (inclusive).
until query string — ISO-8601 end time (inclusive).
include_backups query bool — Also read rotated log files.
format query string — Set to "csv" to download a CSV export instead of JSON.
Example response
{
  "status": "success",
  "count": 1,
  "summary": {
    "total_events": 1,
    "unique_targets": 1,
    "mitigated": 0,
    "peak_gbps": 0.135,
    "peak_pps": 17681.06,
    "peak_target": "185.206.82.129",
    "by_event": { "END": 1 },
    "by_severity": { "LOW": 1 }
  },
  "attacks": [
    {
      "ts": "2026-06-02T22:37:00Z",
      "event": "END",
      "attack_id": "3fc6da314b0c5253",
      "target": "185.206.82.129",
      "severity": "LOW",
      "attack_type": "Threshold",
      "gbps": 0.135,
      "pps": 17681.06,
      "sources": 85,
      "countries": 15,
      "duration_seconds": 480,
      "mitigated": false,
      "first_seen": "2026-06-02T22:29:00Z",
      "ended_at": "2026-06-02T22:37:00Z"
    }
  ]
}

Alerts

GETPUT /config/alerts

View or update local alert settings (Telegram / email). PUT applies live — channels are rebuilt without a restart. Send only the fields you want to change.

Request body (JSON)
enabled bool — Master switch for alerting.
min_severity string — Minimum severity to alert on (LOW | MEDIUM | HIGH | CRITICAL).
on_start bool — Alert when an attack starts.
on_end bool — Alert when an attack ends.
telegram_enabled bool — Enable the Telegram channel.
telegram_bot_token string — Telegram bot token.
telegram_chat_id string — Telegram chat / channel ID.
email_enabled bool — Enable the email channel.
smtp_host string — SMTP server host.
smtp_port int — SMTP port (e.g. 587).
smtp_username string — SMTP username.
smtp_password string — SMTP password.
email_from string — Sender address.
email_to string|array — Recipient(s): array or comma-separated string.
Example response
{
  "success": true,
  "alerts_settings": {
    "enabled": false,
    "min_severity": "HIGH",
    "on_start": true,
    "on_end": true,
    "telegram_enabled": false,
    "telegram_bot_token": "",
    "telegram_chat_id": "",
    "email_enabled": false,
    "smtp_host": "",
    "smtp_port": 587,
    "smtp_username": "",
    "email_from": "",
    "email_to": null,
    "active_channels": null
  }
}
POST /alerts/test

Send a synchronous test message to every configured channel. No body.

Example response
{
  "success": true,
  "message": "test alert sent successfully",
  "channels": ["telegram", "email"]
}

Service

POST /reload

Re-read config.ini from disk and apply the whole program live (detection thresholds, filters, smart detection, webhook, alerts, attack log, BGP announce/FlowSpec settings, and blocklist feeds) — no restart. No body. Note: API port/key/base-path, smart-detection memory size and BGP neighbor topology still require a service restart.

Example response
{
  "success": true,
  "message": "Configuration reloaded and applied live. Note: API port/key/base-path, smart-detection memory size and BGP neighbor topology require a service restart to change.",
  "source_path": "config.ini",
  "alert_channels": null,
  "attack_log_enabled": true,
  "bgp_reloaded": true,
  "blocklist_reloaded": true,
  "warnings": null
}

Detection Configuration

GET returns the current values; PUT accepts a partial flat JSON body and applies immediately.

GET /config

Full current configuration (all sections combined).

GETPUT /config/thresholds

Detection severity thresholds (bandwidth & PPS per level).

Request body (JSON)
min_bandwidth_gbps float — Minimum bandwidth to flag an attack.
high_bandwidth_gbps float — HIGH severity bandwidth threshold.
medium_bandwidth_gbps float — MEDIUM severity bandwidth threshold.
critical_bandwidth_gbps float — CRITICAL severity bandwidth threshold.
high_pps int — Baseline packets-per-second threshold.
syn_flood_pps int — TCP SYN flood PPS threshold.
ack_flood_pps int — TCP ACK flood PPS threshold.
rst_flood_pps int — TCP RST flood PPS threshold.
fin_flood_pps int — TCP FIN flood PPS threshold.
udp_flood_pps int — UDP flood PPS threshold.
icmp_flood_pps int — ICMP flood PPS threshold.
min_sources_distributed int — Min sources to classify as distributed.
min_sources_botnet int — Min sources to classify as botnet.
min_countries_global int — Min countries for a global attack.
tcp_conn_ratio_threshold int — TCP connection-ratio heuristic threshold.
Example response
{
  "success": true,
  "thresholds": {
    "min_bandwidth_gbps": 0.4,
    "high_bandwidth_gbps": 1,
    "medium_bandwidth_gbps": 0.6,
    "critical_bandwidth_gbps": 2.5,
    "high_pps": 50000,
    "syn_flood_pps": 50000,
    "ack_flood_pps": 30000,
    "rst_flood_pps": 10000,
    "fin_flood_pps": 10000,
    "udp_flood_pps": 50000,
    "icmp_flood_pps": 15000,
    "min_sources_distributed": 80,
    "min_sources_botnet": 80,
    "min_countries_global": 3,
    "tcp_conn_ratio_threshold": 100
  }
}
GETPUT /config/timing

Detection window length and check interval.

Request body (JSON)
check_interval_seconds int — How often the detector runs a cycle.
detection_window_minutes int — Lookback window analysed each cycle.
Example response
{
  "success": true,
  "timing": { "check_interval_seconds": 60, "detection_window_minutes": 1 }
}
GETPUT /config/advanced

Advanced heuristics and attack-lifecycle tuning.

Request body (JSON)
tcp_conn_ratio_threshold int — TCP connection-ratio heuristic.
udp_distinct_ports_threshold int — Distinct UDP ports heuristic.
icmp_avg_packet_size_threshold int — ICMP average packet size heuristic.
attack_end_grace_cycles int — Cycles of silence before marking an attack ENDED.
ended_attack_retention_cycles int — Cycles to keep ENDED attacks (-1 = forever).
GETPUT /config/filters

Traffic filtering applied to flow queries.

Request body (JSON)
dst_net_role string — Destination network role to monitor (e.g. customers).
in_if_boundary string — Ingress interface boundary filter (optional).
GETPUT /config/display

Display / result limits.

Request body (JSON)
max_sources_display int — Top sources to include.
max_countries_display int — Top countries to include.
max_asns_display int — Top ASNs to include.
max_flows_display int — Top flows to include.
max_src_ports_display int — Top source ports to include.
max_dst_ports_display int — Top destination ports to include.
result_limit int — Overall query result cap.
GET /config/network

Monitored / protected networks (from network.yaml).

Example response
{
  "success": true,
  "network": {
    "enabled": true,
    "network_config_file": "network.yaml",
    "total_networks": 1,
    "networks": ["0.0.0.0/0"]
  }
}
GETPUT /config/attack-log

Attack-history log settings. PUT reopens the logger live.

Request body (JSON)
enabled bool — Enable JSONL attack logging.
file string — Log file path.
max_size_mb int — Rotate after this size.
max_backups int — Rotated files to keep.
Example response
{
  "success": true,
  "attack_log_settings": {
    "enabled": true,
    "file": "/var/log/coredetection/attacks.jsonl",
    "max_size_mb": 50,
    "max_backups": 5
  }
}

System Configuration

Changes that affect the listening socket (port/key/base-path) take effect after a restart.

GETPUT /config/database

Flow data source connection.

Request body (JSON)
clickhouse_host string — Flow store host.
clickhouse_port int — Flow store port.
clickhouse_user string — Username.
clickhouse_password string — Password.
clickhouse_database string — Database name.
connection_timeout int — Connection timeout (seconds).
GETPUT /config/api

API server settings (key is masked on read).

Request body (JSON)
api_enabled bool — Enable the API server.
api_port int — Listening port (restart required).
api_key string — API key (restart required).
api_base_path string — Base path (restart required).
GETPUT /config/debug

Debug mode and log output destinations.

GETPUT /config/webhook

Webhook integration (used with the CoreTech portal; disable for standalone).

Request body (JSON)
webhook_enabled bool — Enable webhook delivery.
webhook_url string — Destination URL.
webhook_auth_header string — Auth header name.
webhook_auth_token string — Auth token value.
detector_id string — Identifier sent with each event.
debug_webhook_save bool — Save outgoing payloads to disk.
debug_webhook_dir string — Directory for saved payloads.

BGP Mitigation

GET /bgp/status

BGP speaker status.

Example response
{
  "running": true,
  "enabled": true,
  "local_asn": 65001,
  "router_id": "185.19.38.78",
  "neighbors_total": 1,
  "sessions_established": 1,
  "routes_announced": 0,
  "uptime": "2m45s"
}
GETPUT /bgp/config

BGP configuration and per-severity announce gates.

Example response
{
  "enabled": true,
  "local_asn": 65001,
  "router_id": "185.19.38.78",
  "default_mitigation_nexthop": "10.10.20.1",
  "announce_critical_attacks": true,
  "announce_high_attacks": true,
  "announce_medium_attacks": false,
  "announce_low_attacks": false,
  "communities": {
    "blackhole": "65001:666",
    "mitigation": "65001:100",
    "high_prio": "65001:200",
    "no_export": "65535:65281"
  }
}
GET /bgp/neighbors

List configured BGP neighbors and their session state.

Example response
{
  "total_neighbors": 1,
  "neighbors": [
    {
      "id": "static-1",
      "name": "Core-Router-1",
      "neighbor_ip": "156.229.62.252",
      "neighbor_asn": 213642,
      "session_type": "ebgp",
      "session_state": "established",
      "nexthop": "10.10.20.1",
      "enabled": true,
      "source": "config_file"
    }
  ]
}
GET /bgp/neighbors/{id}

Details for a single neighbor.

Parameters
id path string — Neighbor address or ID.
POST /bgp/neighbors/reset/{id}

Reset (bounce) the BGP session with a neighbor.

Parameters
id path string — Neighbor address or ID.
GET /bgp/sessions

Active BGP session summary.

GET /bgp/routes

All currently announced routes (blackhole + attack).

Example response
{ "total_routes": 0, "routes": {} }
GETPOSTDELETE /bgp/routes/manual

List, manually announce, or withdraw a blackhole route.

Request body (JSON)
destination_ip string required — Target IP to blackhole (POST).
prefix_length int — Prefix length (default 32).
nexthop_ip string — Override next-hop (optional).
communities array — BGP communities to attach (optional).
description string — Free-text note (optional).
GET /bgp/routes/attack

Routes announced automatically in response to attacks.

BGP FlowSpec

Targeted filtering (RFC 5575 / RFC 8955 — same NLRI on the wire). Drops, rate-limits, forwards (accept/nexthop), redirects (RT), or marks (DSCP) matched traffic instead of blackholing the whole victim. Requires FlowSpec-capable routers.

GETPUT /config/flowspec

View or update FlowSpec settings. Toggling "enabled" applies live — peers are re-negotiated automatically, no restart needed.

Request body (JSON)
enabled bool — Enable FlowSpec mitigation (announced instead of blackhole).
default_action string — Default action: drop | rate-limit | accept | redirect | mark.
rate_limit_bps int — Bandwidth ceiling (bits/sec) when action = rate-limit.
Example response
{ "enabled": false, "default_action": "drop", "rate_limit_bps": 1000000000 }
POST /flowspec/apply

Manually re-negotiate the FlowSpec address family with all peers (bounces sessions) to apply changes live without a restart. No body.

Example response
{
  "status": "success",
  "message": "FlowSpec re-negotiated with all peers. No service restart required.",
  "enabled": true
}
GETPOSTDELETE /flowspec/rules

List active FlowSpec rules, add a targeted manual rule, or withdraw one.

Parameters
id query string — Rule ID to withdraw (DELETE) — or pass in JSON body.
Request body (JSON)
dst_prefix string required — Destination IP/prefix to protect.
dst_prefix_len int — Destination prefix length (default 32).
src_prefix string — Source prefix to match (optional).
src_prefix_len int — Source prefix length (optional).
protocol int — IP protocol number (6=TCP, 17=UDP, 1=ICMP).
dst_port int — Destination port to match (optional).
src_port int — Source port to match (e.g. 53 for DNS).
min_packet_len int — Match packets with length >= this value.
tcp_flags array — TCP flags: syn, ack, fin, rst, push, urgent, ece, cwr — combine with | (e.g. syn|ack), negate with !fin.
fragmentation_flags array — dont-fragment, is-fragment, first-fragment, last-fragment, not-a-fragment.
action string — drop | discard | rate-limit | accept | redirect | mark (defaults to configured action).
rate_limit_bps int — Rate ceiling when action = rate-limit.
action_params object — redirect_target_as, redirect_target_value, redirect_ipv4, dscp, ipv4_nexthops, terminal, sample.
ipv4_nexthops array — Scrubbing nexthops when action = accept (FastNetMon-compatible).
description string — Free-text note (optional).
Example response
{ "total_rules": 0, "rules": {} }

IP Blocklist

Ingests IP/CIDR threat feeds and enforces them via FlowSpec source-prefix drop (0.0.0.0/0 destination match). Requires flowspec.enabled=true and blocklist.enforce=true. Feeds are defined in config.ini under [blocklist_feed_*] sections.

GET /blocklist/status

Subsystem status: entry count, applied FlowSpec rules, feed count, and last refresh result.

Example response
{
  "enabled": false,
  "enforce": true,
  "flowspec_ready": false,
  "entry_count": 0,
  "applied_rules": 0,
  "feed_count": 0,
  "last_refresh_ok": true,
  "feeds": []
}
GETPUT /blocklist/config

View or update blocklist settings. PUT applies live and persists to config.ini.

Request body (JSON)
enabled bool — Enable blocklist ingestion and periodic refresh.
enforce bool — Push FlowSpec drop rules for each entry (requires FlowSpec).
refresh_interval_minutes int — How often to reload feeds automatically.
Example response
{
  "enabled": false,
  "enforce": true,
  "refresh_interval_minutes": 60,
  "feeds": [],
  "manual_entries": []
}
GET /blocklist/entries

Merged list of all entries from feeds and manual_entries.

Example response
{ "total_entries": 0, "entries": [] }
POST /blocklist/refresh

Reload all feeds immediately and reapply FlowSpec rules. No body.

Example response
{
  "status": "success",
  "message": "Blocklist refreshed successfully",
  "entry_count": 0,
  "applied_rules": 0,
  "last_refresh_ok": true
}

Smart Detection

GET /smart-detection/memory

Attack-memory contents (learned attack signatures).

GET /smart-detection/stats

Smart-detection statistics and memory usage.

Example response
{
  "success": true,
  "enabled": true,
  "stats": {
    "total_attacks": 517,
    "memory_used": 517,
    "memory_max": 5000,
    "memory_percent": 10.34,
    "oldest_attack": "2026-05-25 13:49:15",
    "newest_attack": "2026-06-03 01:29:00"
  }
}

License

GET /license/server-id

This server's unique ID, required to request a license.

Example response
{ "server_id": "e95e34e0638442d7a9e05f75ace0342d" }
GET /license/status

Current license status and validity.

Example response
{
  "valid": true,
  "server_id": "e95e34e0638442d7a9e05f75ace0342d",
  "product": "CoreEdge Mitigation (On-Cloud)",
  "customer": "mert arda",
  "is_lifetime": false,
  "expires_at": "2026-12-14T03:00:00+03:00",
  "days_remaining": 194
}
POST /license/reload

Reload license.lic without restarting the service. No body.

Worked examples

# live attacks, filtered by severity
curl -H "X-API-Key: YOUR_KEY" \
  "http://localhost:9009/CoreDetection/api/v0/attacks/active?severity=HIGH"

# export a CSV report (incl. rotated logs)
curl -H "X-API-Key: YOUR_KEY" \
  "http://localhost:9009/CoreDetection/api/v0/reports/attacks?include_backups=true&format=csv" -o attacks.csv

# enable Telegram alerts (applied live)
curl -X PUT -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"enabled":true,"min_severity":"HIGH","telegram_enabled":true,"telegram_bot_token":"123:ABC","telegram_chat_id":"-1001"}' \
  http://localhost:9009/CoreDetection/api/v0/config/alerts

# enable FlowSpec and re-negotiate with peers
curl -X PUT -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"enabled":true,"default_action":"drop"}' \
  http://localhost:9009/CoreDetection/api/v0/config/flowspec

curl -X POST -H "X-API-Key: YOUR_KEY" \
  http://localhost:9009/CoreDetection/api/v0/flowspec/apply

# FlowSpec rule — SYN flood to scrubbing center
curl -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"dst_prefix":"203.0.113.5/32","protocol":6,"tcp_flags":["syn"],"action":"accept","ipv4_nexthops":["11.22.33.44"]}' \
  http://localhost:9009/CoreDetection/api/v0/flowspec/rules

# FlowSpec rule — redirect to scrubbing RT
curl -X POST -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"dst_prefix":"203.0.113.5/32","action":"redirect","action_params":{"redirect_target_as":65000,"redirect_target_value":666}}' \
  http://localhost:9009/CoreDetection/api/v0/flowspec/rules

# refresh blocklist feeds and apply FlowSpec drop rules
curl -X POST -H "X-API-Key: YOUR_KEY" \
  http://localhost:9009/CoreDetection/api/v0/blocklist/refresh

# reload entire config.ini live (includes blocklist feeds)
curl -X POST -H "X-API-Key: YOUR_KEY" \
  http://localhost:9009/CoreDetection/api/v0/reload

Status codes

CodeMeaning
200Success
201Created (e.g. a FlowSpec rule announced)
400Bad request (invalid JSON or parameters)
401Unauthorized (missing/invalid API key)
429Too many requests (rate limit exceeded — see Retry-After header)
404Not found
405Method not allowed
500Internal server error
503Subsystem unavailable (e.g. BGP not initialized)
Error responses include a description: { "success": false, "error": "..." }.