2
Files
caddy-opnsense-blocker/docs/api.md

5.3 KiB

HTTP API

The daemon serves a small JSON API used by the built-in web UI.

General behavior

  • All endpoints are served from the same address as the web UI.
  • Responses are JSON.
  • Error responses use the shape {"error":"..."}.
  • Unsupported HTTP methods return 405 Method Not Allowed.
  • There is no built-in authentication or TLS.

GET /healthz

Liveness probe.

Example response:

{
  "status": "ok",
  "time": "2026-03-12T18:22:11Z"
}

GET /api/overview

Returns summary counters, chart data, and dashboard leaderboards.

Query parameters:

  • limit

    • optional
    • default: 50
    • maximum: 1000
  • hours

    • optional
    • default: 24
    • used for the top activity leaderboards returned in the same payload Main response fields:
  • total_events

  • total_ips

  • blocked_ips

  • review_ips

  • allowed_ips

  • observed_ips

  • activity_since

  • activity_buckets

  • methods

  • bots

  • top_bot_ips_by_events

  • top_non_bot_ips_by_events

  • top_bot_ips_by_traffic

  • top_non_bot_ips_by_traffic

  • top_sources

  • top_urls

  • recent_ips

  • recent_events

GET /api/events

Returns a paginated slice of recent raw events.

Query parameters:

  • limit
    • optional
    • default: 100
    • maximum: 1000
  • page
    • optional
    • default: 1
    • one-based page number
  • show_known_bots
    • optional
    • default: true
    • when false, verified bots are hidden from the log
  • show_allowed
    • optional
    • default: true
    • when false, rows whose current IP state is allowed are hidden
  • review_only
    • optional
    • default: false
    • when true, only requests whose current IP state is review are returned

Main response fields:

  • items
  • page
  • limit
  • has_prev
  • has_next

Each event includes:

  • source and profile names
  • timestamps
  • remote and client IPs
  • host, method, URI, path, status, and User-Agent
  • decision, primary reason, all reasons, and whether it was enforced
  • raw Caddy JSON
  • current IP state and manual override

GET /api/ips

Returns current IP state rows.

Query parameters:

  • limit
    • optional
    • default: 100
    • maximum: 1000
  • state
    • optional
    • filter by one state such as review, blocked, allowed, or observed

Each row includes:

  • ip
  • first_seen_at
  • last_seen_at
  • last_source_name
  • last_user_agent
  • latest_status
  • total_events
  • state
  • state_reason
  • manual_override
  • last_event_id
  • updated_at

GET /api/recent-ips

Returns aggregated IP rows over a recent time window.

Query parameters:

  • hours
    • optional
    • default: 24
    • values less than or equal to zero fall back to 24
  • limit
    • optional
    • default: 200
    • maximum: 1000

Each row includes:

  • ip
  • source_name
  • state
  • events
  • last_seen_at
  • reason
  • manual_override
  • optional bot
  • actions

actions contains:

  • can_block
  • can_unblock
  • can_clear_override

GET /api/ips/{ip}

Returns the complete details for one IP address.

Response fields:

  • state
  • recent_events
  • decisions
  • backend_actions
  • optional investigation
  • opnsense
  • actions

The current implementation returns up to:

  • 100 recent events
  • 100 decision records
  • 100 backend action records

POST /api/ips/{ip}/investigate

Forces a fresh investigation for the selected IP and returns the updated IPDetails payload.

This bypasses the cached investigation for that request.

No request body is required.

Action endpoints

These endpoints accept an optional JSON body:

{
  "actor": "alice@example.net",
  "reason": "short human-readable explanation"
}

If omitted:

  • actor defaults to web-ui
  • reason defaults to an action-specific fallback

All action endpoints return the updated IPDetails payload on success.

POST /api/ips/{ip}/block

  • Sets a manual force-block override.
  • Default reason: manual block.
  • If OPNsense is enabled, the daemon adds the IP to the configured alias if it is missing.

POST /api/ips/{ip}/unblock

  • Sets a manual force-allow override.
  • Default reason: manual allow.
  • If OPNsense is enabled, the daemon removes the IP from the configured alias if it is present.

POST /api/ips/{ip}/clear-override

  • Removes the local manual override.
  • Default reason: manual override cleared.
  • Does not directly call OPNsense.

POST /api/ips/{ip}/reset

Backwards-compatible alias for clear-override.

Response model details

investigation

When present, investigation may contain:

  • ip
  • updated_at
  • error
  • bot
  • reverse_dns
  • registration
  • reputation

bot

  • provider_id
  • name
  • icon
  • method
  • verified

reverse_dns

  • ptr
  • forward_confirmed

registration

  • source
  • handle
  • name
  • prefix
  • organization
  • country
  • abuse_email

reputation

  • spamhaus_lookup
  • spamhaus_listed
  • optional spamhaus_codes
  • optional error

opnsense

  • configured
  • present
  • checked_at
  • optional error

Example manual block request

curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"actor":"cli","reason":"confirmed credential stuffing"}' \
  http://127.0.0.1:9080/api/ips/203.0.113.10/block

Example recent IP query

curl 'http://127.0.0.1:9080/api/recent-ips?hours=24&limit=250'