Skip to content

Dashboard API

Krawl exposes a JSON API for everything the dashboard shows: IP statistics, captured credentials, attack detections, banlist exports and the Cloudflare integration.

All endpoints live under the dashboard secret path, so a call looks like:

https://your-krawl-instance/<DASHBOARD-PATH>/api/export-ips

Requests to /api/... without the secret path prefix are indistinguishable from any other scan and get a honeypot page — that is intentional.

Looking for the third-party services Krawl calls out to (geolocation, IP reputation)? That's External APIs.

Interactive documentation

Krawl serves a live OpenAPI schema and Swagger UI, always in sync with the running version:

Path Content
/<DASHBOARD-PATH>/docs Swagger UI — browse and try every endpoint
/<DASHBOARD-PATH>/openapi.json Raw OpenAPI schema

Only /api/* routes are in the schema; the dashboard pages and HTMX fragment endpoints are excluded. A read-only copy for the current release is in the API reference.

Authentication

Read endpoints are reachable with the secret path alone. Write actions (banning, tracking, deception page management, webhooks) need a session.

# Obtain a session cookie
curl -c krawl.cookies -X POST \
  "https://your-krawl-instance/<DASHBOARD-PATH>/api/auth" \
  -H "Content-Type: application/json" \
  -d '{"password": "your-dashboard-password"}'

# Use it
curl -b krawl.cookies -X POST \
  "https://your-krawl-instance/<DASHBOARD-PATH>/api/track-ip" \
  -H "Content-Type: application/json" \
  -d '{"ip_address": "203.0.113.5"}'

Sessions are HTTP-only cookies valid for 12 hours. Failed logins are rate-limited per IP with exponential backoff; in scalable mode both sessions and lockout counters are shared across replicas via Redis. See Dashboard → Authentication.

Endpoints marked 🔒 below require that session and return 401 {"error": "Unauthorized"} without one.

Endpoints

Session

Method Path Description
POST /api/auth Exchange the dashboard password for a session cookie
POST /api/auth/logout Invalidate the current session
GET /api/auth/check Report whether the current request is authenticated

IP data

Method Path Description
GET /api/all-ips Paginated list of every observed IP
GET /api/all-ip-stats Statistics for all IPs
GET /api/ip-stats/{ip} Full detail for one IP: category, scores, geolocation, reputation
GET /api/attackers IPs classified as attackers
GET /api/top-ips Most active IPs by request count
GET /api/top-paths Most requested paths
GET /api/top-user-agents Most seen user agents

Attacks and captures

Method Path Description
GET /api/honeypot Honeypot trigger events
GET /api/credentials Captured login attempts
GET /api/download-credentials Captured credentials as a downloadable file
GET /api/attack-types Detected attack attempts
GET /api/attack-types-stats Attack counts per type
GET /api/attack-types-daily Top attack types per bucket (days, offset_days, slot, limit). Returns attack_types, dates, bucket_hours (1, 4 or 24), slot_totals (totals for the selected slot, else null) and colours (type to its severity band and shade)
GET /api/attack-facets Detections per severity band and per rule for a period (days, offset_days, slot)
GET /api/raw-request/{log_id} Full raw HTTP request for one access log entry
GET /api/attachments/{log_id} Files uploaded in that request — see Attachments
GET /api/attachments/{log_id}/download/{index} Download one of those files

Banning and export

Method Path Description
GET /api/export-ips Export the banlist. Supports ?categories=, ?fwtype=, ?merge_banlists= and ?exclude_cdn= — see Firewall Exporters
GET /api/banlist-sources Upstream banlists currently merged into the local one
POST 🔒 /api/ban-override Manually ban or unban an IP
POST 🔒 /api/timeout-exempt Exempt an IP from automatic rate-limit time-bans
POST 🔒 /api/track-ip Start tracking an IP

If banlist.export_path is configured, the banlist is also published on that unauthenticated path outside the dashboard prefix, for other Krawl instances to consume. See Krawl Banlist.

Deception pages

Method Path Description
GET 🔒 /api/download-generated-page Download one deception page
POST 🔒 /api/download-generated-pages-zip Download a selection as a zip
POST 🔒 /api/upload-generated-page Upload one deception page
POST 🔒 /api/upload-generated-pages-bulk Upload a zip of deception pages
POST 🔒 /api/delete-generated-pages Delete deception pages

See Deception Pages for the bulk workflows.

Cloudflare webhook

Method Path Description
GET 🔒 /api/webhooks/status Current integration state and last sync result
POST 🔒 /api/webhooks/cloudflare/save Store account ID and API token
POST 🔒 /api/webhooks/cloudflare/sync Trigger a sync immediately instead of waiting for the interval
DELETE 🔒 /api/webhooks/cloudflare/config Remove the stored configuration

See Cloudflare Banlist Sync.

Metrics

Prometheus metrics are served at /<DASHBOARD-PATH>/metrics, outside the /api prefix and outside the OpenAPI schema. See Metrics & Monitoring.

Attachments

When an attacker uploads a file — a webshell, a malware sample, an exfiltration payload — Krawl stores the raw request, and the attachment endpoints let you pull the uploaded bytes back out for analysis.

Two upload shapes are recognised:

  • multipart/form-data — each part is exposed as a separate attachment, keeping its form field name, filename and content type.
  • Raw body uploads (PUT/POST of a file as the whole body) — the body becomes a single attachment, named after the request path.
# What did they upload?
curl -b krawl.cookies \
  "https://your-krawl-instance/<DASHBOARD-PATH>/api/attachments/12345"
{
  "attachments": [
    {
      "index": 0,
      "name": "file",
      "filename": "shell.php",
      "content_type": "application/x-php",
      "size": 4213
    }
  ]
}
# Pull it down for analysis
curl -b krawl.cookies -OJ \
  "https://your-krawl-instance/<DASHBOARD-PATH>/api/attachments/12345/download/0"

In the dashboard the same thing is a paperclip button in the raw request modal: it lists the attachments and downloads the one you click.

Handle downloads as hostile. These are files an attacker chose to send you. Open them in a sandbox, not on the machine running your browser.

Attachments are reconstructed from the stored raw request, which means:

  • Request bodies larger than 64 KB are never buffered, so uploads above that size leave a logged request with no retrievable attachment.
  • They disappear with the access log itself, on the retention schedule.