HomeDocsOpenAPI
OpenAPI v1 PRO only HTTPS required Bearer Token

FOXWAF OpenAPI Reference

Call WAF management endpoints directly with an API key — no panel login required. Ideal for automation, monitoring alerts, and CI/CD. Every request validates PRO status in real time; scopes grant fine-grained access; high-risk operations stay blocked.

https://<WAF-host>:<port>/openapi/v1/<path>

AuthAuthorization: Bearer <api_key>
Path map/openapi/v1/* → internal /api/*
Rate limit120 req / key / 60s
StatusComing soon · Docs first
Notice: The OpenAPI channel will soon launch for PRO users. This reference matches the implementation — try it in a test environment. Watch Announcements for the release announcement.

1. Overview

FOXWAF OpenAPI lets PRO users call WAF management endpoints via API key, fully separate from the panel's encrypted channel.

2. Quickstart

Create an API key

  1. Sign in to the FOXWAF panel → SettingsOpenAPI keys
  2. Click "+ Generate key", set a name, pick scopes, optional expiry
  3. The dialog shows the full key once — copy and store it immediately; it cannot be viewed again

First request

WAF="https://127.0.0.1:8088" KEY="fwk_your-prefix_your-secret" curl -k \ -H "Authorization: Bearer $KEY" \ "$WAF/openapi/v1/acl/rules"

-k Skips self-signed cert verification; remove in production after installing a trusted certificate.

3. API Key management

Key format

fwk_<10-char-prefix>_<32-char-secret>

Example: fwk_lu2LAk9HFj_qL9ioS4cmjVhW7dEfBxzRpYKnuA1G

Panel actions

ActionDescription
CreateSet name, scopes, expiry; secret shown only once at creation; quick select all / clear / read-only
Disable / enableTemporarily disable a key without deleting it
RevokePermanently delete; takes effect immediately; in-flight calls get invalid_key
Revoke selectedRevoke multiple selected keys at once
Revoke allRevoke all keys in one action

Long scope lists collapse automatically; click +N to expand.

Panel management APIs (encrypted /api channel, login required)

These endpoints cannot be called with an OpenAPI key — prevents privilege escalation if a key leaks.

MethodPathDescription
GET/api/openapi/keysList keys
POST/api/openapi/keysCreate (returns plaintext secret once)
POST/api/openapi/keys/:id/toggleEnable/disable; body {"enabled":true/false}
DELETE/api/openapi/keys/:idRevoke one
DELETE/api/openapi/keysBatch revoke body {"ids":[1,2,3]}; revoke all body {"all":true}

Key list fields

FieldDescription
nameDisplay name
prefixKey prefix (shown as fwk_prefix_***)
scopesScope list
enabledEnabled
expire_atExpiry (Unix seconds, 0 = never)
last_used_atLast used (persisted asynchronously every 30s)

4. Scopes

At least one scope is required when creating a key.

Preset scopes

ScopeDescription
*:readAll modules read-only
*:writeAll modules read/write (includes read)
acl:read / acl:writeACL rules read / read-write
cc:read / cc:writeCC protection read / read-write
custom-rules:read / custom-rules:writeCustom rules read / read-write
site:read / site:writeSite management read / read-write
settings:read / settings:writeGlobal settings read / read-write
attack:read cache:read rule:read monitor:read obs:read plugins:read waf:read letsencrypt:read feedbacks:read

Each module has a :write scope; use *:read or *:write if unsure.

Scope to path mapping

Path prefixRequired module
/openapi/v1/acl/*acl
/openapi/v1/cc/*cc
/openapi/v1/custom-rules/*custom-rules
/openapi/v1/sites/openapi/v1/site/*/openapi/v1/health*site
/openapi/v1/attack/*attack
/openapi/v1/cache/*cache
/openapi/v1/rule*/openapi/v1/rules*rule
/openapi/v1/monitor/*/openapi/v1/traffic/*/openapi/v1/statsmonitor / traffic / stats
/openapi/v1/obs/*obs
/openapi/v1/cert-template*cert-template
/openapi/v1/plugins/*plugins
/openapi/v1/waf/*waf
/openapi/v1/settingssettings
/openapi/v1/feedbacksfeedbacks
/openapi/v1/letsencrypt/*letsencrypt
/openapi/v1/cert/*cert
/openapi/v1/realtime/*realtime
/openapi/v1/qrcodeqrcode
/openapi/v1/ping, /openapi/v1/config, /openapi/v1/maintenance-server*, /openapi/v1/captcha/*, /openapi/v1/waf/languagePublic (no scope)

5. Request format

Headers

Authorization: Bearer <api_key> Content-Type: application/json # required for POST / PUT / DELETE

Path map

OpenAPI paths map 1:1 to internal panel APIs:

/openapi/v1/<path> → /api/<path>
OpenAPI pathInternal path
/openapi/v1/acl/rules/api/acl/rules
/openapi/v1/cc/rules/5/api/cc/rules/5
/openapi/v1/sites/api/sites

Query parameters

Paginated endpoints require page and page_size:

curl -k -H "Authorization: Bearer $KEY" \ "$WAF/openapi/v1/attack/logs?page=1&page_size=20"

6. Error codes

All errors use this format:

{ "error": "Error message", "code": "error_code" }
HTTPcodeReason
401missing_tokenMissing Authorization: Bearer header
401invalid_keyKey not found or wrong secret
403https_requiredHTTP used instead of HTTPS
403key_disabledKey manually disabled
403key_expiredKey past configured expiry
403pro_requiredPRO license expired or invalid (checked live)
403scope_deniedKey scopes missing required permission
403endpoint_not_exposedPath not exposed (sensitive module)
429rate_limitedRate limited (120 requests per key per 60s)

PRO-gated features (CC, custom rules, observation room, HTTP/3, etc.) also return {"error":"PRO license required","pro_required":true}

7. Rate limits

ItemValue
GranularityPer API key
Window60-second fixed window
Limit120 requests / 60 seconds
Response when exceededHTTP 429 + {"code":"rate_limited"}

8. Endpoint reference

Response conventions
  • Write success:Returns {"message":"…"}; create endpoints include resource IDs
  • Read:Returns the corresponding data object (see examples below)
  • PRO gating:CC, custom rules, observation room, etc. return 403 + pro_required: true when PRO expires
  • Examples use WAF="https://127.0.0.1:8088" and KEY="fwk_…"

8.1 ACL rules acl

GET/openapi/v1/acl/rulesList rules
POST/openapi/v1/acl/rulesCreate rule
PUT/openapi/v1/acl/rules/:idUpdate rule
POST/openapi/v1/acl/rules/:id/toggleEnable / disable
DELETE/openapi/v1/acl/rules/:idDelete rule
GET /openapi/v1/acl/rules List rules
curl -k -H "Authorization: Bearer $KEY" "$WAF/openapi/v1/acl/rules"

Response example

{ "rules": [ { "id": 1, "type": "global", "rule_type": "ip", "pattern": "1.2.3.4", "action": "block", "enabled": true, "description": "Malicious IP" } ] }
POST /openapi/v1/acl/rules Create rule

Request body fields

FieldTypeRequiredDescription
typestringRequiredglobal or host (per domain)
rule_typestringRequiredip, ua, url, header, country, etc.
patternstringRequiredMatch pattern
actionstringRequiredblock or allow
enabledboolRequiredEnabled
hoststringConditionalRequired when type=host
descriptionstringOptionalNotes
# Block IP curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"type":"global","rule_type":"ip","pattern":"1.2.3.4","action":"block","enabled":true,"description":"Malicious scan"}' \ "$WAF/openapi/v1/acl/rules" # Block UA per host curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"type":"host","host":"example.com","rule_type":"ua","pattern":"sqlmap","action":"block","enabled":true}' \ "$WAF/openapi/v1/acl/rules"

Response

{"id": 10, "message": "ACL rule created"}
PUT /openapi/v1/acl/rules/:id Update rule

Request body fields same as create rule.

curl -k -X PUT -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"type":"global","rule_type":"ip","pattern":"1.2.3.4","action":"allow","enabled":true}' \ "$WAF/openapi/v1/acl/rules/10"
POST /openapi/v1/acl/rules/:id/toggle Enable / disable

Body: {"enabled": false}

8.2 CC protection cc Pro

GET/openapi/v1/cc/rulesList CC rules
POST/openapi/v1/cc/rulesCreate CC rule
PUT/openapi/v1/cc/rules/:idUpdate
DELETE/openapi/v1/cc/rules/:idDelete
GET/openapi/v1/cc/statsStats overview
GET/openapi/v1/cc/logsLogs (paginated)
DELETE/openapi/v1/cc/logsDelete logs
POST/openapi/v1/cc/clear-countersClear counters
POST /openapi/v1/cc/rules Create CC rule
FieldTypeRequiredDescription
hoststringRequiredHost; * matches all
pathstringRequiredPath prefix
thresholdintRequiredMax requests in window
windowintRequiredWindow (seconds)
ban_durationintRequiredBan duration (seconds)
actionstringRequiredblock or challenge
enabledboolRequiredEnabled
curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"host":"*","path":"/api/login","threshold":10,"window":60,"ban_duration":300,"action":"block","enabled":true}' \ "$WAF/openapi/v1/cc/rules"
GET /openapi/v1/cc/stats CC stats & logs
  • /cc/logs requires ?page=1&page_size=20
  • Delete logs body: {"all": true} or {"ids": [1,2,3]}

/cc/stats Response

{"total_blocked": 0, "today_blocked": 0, "active_attacks": 0, "top_blocked_ips": null, "rule_stats": null}

/cc/logs Response

{"logs": null, "total": 0, "page": 1, "page_size": 20, "total_pages": 0}

Write responses

{"message": "CC counters cleared"} {"message": "CC rule deleted"} {"message": "CC rule updated"}

8.3 Custom rules custom-rules Pro

GET/openapi/v1/custom-rulesList rules
POST/openapi/v1/custom-rulesCreate rule
PUT/openapi/v1/custom-rules/:idUpdate
POST/openapi/v1/custom-rules/:id/toggleToggle
DELETE/openapi/v1/custom-rules/:idDelete
GET/openapi/v1/custom-rules/exportExport ZIP
POST/openapi/v1/custom-rules/importImport ZIP
POST/openapi/v1/custom-rules/reloadHot reload
POST /openapi/v1/custom-rules Create custom rule
FieldTypeRequiredDescription
namestringRequiredRule name
methodstringRequiredHTTP method; any matches all
actionstringRequiredblock
relationstringRequiredand (all) or or (any)
judgesarrayRequiredJudge conditions
enabledboolOptionalEnabled

judges[] fields

FieldDescription
positionuriparameter_keyparameter_valuerequest_headerrequest_bodyany
keywordKeyword (one of content / rix)
contentContent match (string / array)
rixRegular expression
negateNegate
curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"name":"Block sensitive file probes","method":"any","action":"block","enabled":true,"relation":"or", "judges":[{"position":"uri","keyword":"/.env"},{"position":"uri","keyword":"/.git/config"}]}' \ "$WAF/openapi/v1/custom-rules"

Response

{"message": "Custom rule created", "rule_id": "a1b2c3d4", "rule": {...}}
  • GET /custom-rules/export returns application/zip
  • POST /custom-rules/import form field file (ZIP) → {"message":"Custom rules imported","count":N}
  • POST /custom-rules/reload{"message":"Custom rules reloaded"}

8.4 Site management site

GET/openapi/v1/sitesList sites
POST/openapi/v1/site/addAdd site
POST/openapi/v1/site/add-with-certAdd with cert
POST/openapi/v1/site/deleteDelete site
GET/openapi/v1/site/:id/certificateStandard certificate
GET/openapi/v1/site/:id/sm2-certsSM2 certificate
POST/openapi/v1/site/statusEnable / disable
POST/openapi/v1/site/httpsToggle HTTPS
PUT/openapi/v1/site/updateUpdate site
POST/openapi/v1/site/update-certUpdate site cert
POST/openapi/v1/site/:id/renew-certificateRenew cert
POST/openapi/v1/site/:id/replace-certificateReplace cert
POST/openapi/v1/site/:id/remove-certificateRemove cert
POST/openapi/v1/site/:id/sm2-certsBind SM2 certs
DELETE/openapi/v1/site/:id/sm2-certsUnbind SM2
GET/openapi/v1/healthAll sites health
GET/openapi/v1/health/:idSingle site health
GET /openapi/v1/sites List sites
{ "sites": [ {"id": 1, "name": "Main site", "domain": "example.com", "target_url": "http://127.0.0.1:8080", "status": 1, "enable_https": true} ] }
POST /openapi/v1/site/add Add site
FieldTypeRequiredDescription
namestringYesSite name
domainstringYesDomain(s); comma, semicolon, or newline separated
target_urlstringNoUpstream target URL
enable_httpsboolNoEnable HTTPS (auto self-signed cert)
force_https_redirectboolNoForce HTTP→HTTPS redirect
enable_http2_upstreamboolNoHTTP/2 upstream (default true)
enable_anti_devtools etc.boolNoPro: anti-DevTools, anti-crawler, UA check, response inspection, cache, LB
curl -k -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -X POST "$WAF/openapi/v1/site/add" \ -d '{"name":"Main site","domain":"example.com","target_url":"http://127.0.0.1:8080"}'
{"message": "Site added", "site": {"id": 1, "name": "Main site", "domain": "example.com", "status": 1, "enable_https": false}}
  • Requires site:write. Free tier: up to 2 sites; Pro: unlimited.
  • POST /site/delete body {"id":1}{"message":"Site deleted"}
  • POST /site/add-with-cert uses multipart/form-data with cert_file and key_file
POST /openapi/v1/site/status Site status & certificates
POST/openapi/v1/site/status
Body{"id":1,"status":1}
Response{"message":"Site enabled","status":1}

status: 1=enabled, 0=disabled

POST/openapi/v1/site/https
Body{"id":1,"enable_https":true}
Response{"message":"Site certificate updated","cert_type":"..."}
PUT/openapi/v1/site/update
BodyFull site fields
Response{"message":"Site updated"}
POST/openapi/v1/site/update-cert
Body{"id":1,"cert_name":"..."} or PEM text
Response{"message":"Site certificate updated"}
POST/openapi/v1/site/:id/renew-certificate

No body. Re-issue self-signed certificate.

POST/openapi/v1/site/:id/replace-certificate

multipart: cert_file + key_file. Replace PEM certificate.

POST/openapi/v1/site/:id/remove-certificate

Disable HTTPS without deleting cert store files.

POST/openapi/v1/site/:id/sm2-certs
Body{"sign_cert_id":5,"enc_cert_id":6}
NoteBind SM2 sign/encryption certificates
DELETE/openapi/v1/site/:id/sm2-certs

Remove SM2 binding.

GET /openapi/v1/health Health check
{ "health_status": { "19": {"site_id": 19, "domain": "example.com", "is_alive": true, "status": 200, "latency": 2, "last_check": "2026-06-06 11:44:53"} }, "timestamp": "2026-06-06 11:44:56" }

8.5 Attack logs attack

GET/openapi/v1/attack/logsList logs
GET/openapi/v1/attack/logs/:idSingle entry
GET/openapi/v1/attack/statsStats overview
GET/openapi/v1/attack/ip-groupsGroup by IP
GET/openapi/v1/attack/exportExport JSON/CSV
DELETE/openapi/v1/attack/logsDelete logs
GET /openapi/v1/attack/logs Query attack logs
ParameterDescription
pagePage (required, min=1)
page_sizePage size (required, 1–100)
hostFilter by host
client_ipFilter by client IP
methodFilter by HTTP method
rule_idFilter by rule ID
start_time / end_timeTime range (Unix seconds)
curl -k -H "Authorization: Bearer $KEY" \ "$WAF/openapi/v1/attack/logs?page=1&page_size=20&host=example.com"
{ "logs": [{ "id": 1896080, "method": "GET", "url": "example.com/", "host": "example.com", "rule_name": "[scan-guard] scan-guard: 30x 4xx / 10s", "rule_id": "acl_15", "client_ip": "1.2.3.4", "attack_type": "acl", "created_at": "2026-06-02 18:05:12" }], "total": 1, "page": 1, "page_size": 20 }
GET /openapi/v1/attack/stats Stats & export
  • /attack/export?format=json or format=csv returns a file stream
  • DELETE /attack/logs{"message":"Deleted","affected":N}
{ "total_attacks": 500000, "today_attacks": 0, "top_rules": [{"rule_name": "[scan-guard] ...", "rule_id": "acl_15", "count": 500000}] }

8.6 Cache cache

GET/openapi/v1/cache/statsCache stats
GET/openapi/v1/cache/stats/detailDetailed stats
GET/openapi/v1/cache/filesFile list
POST/openapi/v1/cache/filesRead file content
POST/openapi/v1/cache/configUpdate config
POST/openapi/v1/cache/clearClear cache
DELETE/openapi/v1/cache/files/deleteDelete files
POST/openapi/v1/cache/js-obfuscateStart JS obfuscation
GET/openapi/v1/cache/js-obfuscate/statusObfuscation progress
POST /openapi/v1/cache/config Update cache config
curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"enabled": true, "ttl": 3600}' "$WAF/openapi/v1/cache/config"
  • POST /cache/files body: {"file": "/path"}
  • /cache/clear all sites → {"message":"All cache cleared"}; per site → {"message":"Site cache cleared","host":"..."}
  • POST /cache/js-obfuscate body {"host":"example.com"}{"message":"JS obfuscation started","task_id":"..."}
  • GET /cache/js-obfuscate/status?host=... returns progress percentage

8.7 Rule management rule

GET/openapi/v1/rule/blockRuleIdDisabled rule IDs
GET/openapi/v1/rules/reloadHot reload WAF rules
POST/openapi/v1/rules/statusBatch update rule status
GET/openapi/v1/rule/blockRuleId{"id": [], "rules": []}
GET/openapi/v1/rules/reload{"message": "Rules reloaded", "preserved_status": 609}
POST/openapi/v1/rules/status{"message": "Rule status updated"}

8.8 System monitoring monitor

GET/openapi/v1/monitor/systemCPU / memory / load
GET/openapi/v1/monitor/connectionsConnections
GET/openapi/v1/monitor/historyHistory
GET/openapi/v1/traffic/trendTraffic trend
GET/openapi/v1/statsWAF global stats
GET /openapi/v1/monitor/system System metrics
{ "port_stats": {"port_80_rate": "0 req/s", "port_443_rate": "0 req/s", "total_qps": "0 req/s"}, "cpu_stats": {"usage_percent": "5.94%", "load_average_1": "0.27", "cores": 8}, "memory_stats": {"total": "19.53 GB", "used": "3.73 GB", "available": "15.80 GB", "usage_percent": "19.10%"}, "timestamp": "2026-06-06 11:44:57" }
GET /openapi/v1/stats WAF global stats
{ "total_requests": 125840, "blocked_requests": 312, "cache_hit_rate": "42.50%", "total_rules": 1500, "total_sites": 3, "client_ip": "127.0.0.1" }

8.9 Observation room obs Pro

GET/openapi/v1/obs/configObservation config
PUT/openapi/v1/obs/configUpdate config
GET/openapi/v1/obs/rulesObservation rules
POST/openapi/v1/obs/rulesCreate rule
PUT/openapi/v1/obs/rules/:idUpdate rule
DELETE/openapi/v1/obs/rules/:idDelete rule
GET/openapi/v1/obs/recordsObservation records
GET/openapi/v1/obs/records/:idRecord detail
GET/openapi/v1/obs/records/:id/rawRaw request/response
POST/openapi/v1/obs/records/clearClear records
GET/openapi/v1/obs/statsObservation stats
  • Observation room is PRO-only; when license expires, all calls return {"error":"PRO license required","pro_required":true}
  • Write operations return {"message":"…"}

8.10 Plugin management plugins

GET/openapi/v1/pluginsInstalled plugins
GET/openapi/v1/plugins/configPlugin config
POST/openapi/v1/plugins/configUpdate config
POST/openapi/v1/plugins/reloadReload plugins
POST/openapi/v1/plugins/:name/toggleToggle plugin
POST/openapi/v1/plugins/:name/orderReorder
PUT/openapi/v1/plugins/:name/sitesSite scope
DELETE/openapi/v1/plugins/:nameDelete plugin
POST/openapi/v1/plugins/uploadUpload zip
POST/openapi/v1/plugins/import-urlImport from URL
GET/openapi/v1/plugins/marketplaceMarketplace
GET/openapi/v1/plugins/events/recentRecent events
GET/openapi/v1/plugins/events/statsEvent stats
GET/openapi/v1/plugins/events/wsEvents WebSocket
POST/openapi/v1/plugins/events/clearClear events
curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"enabled": false}' "$WAF/openapi/v1/plugins/ai-shield-1.0.0/toggle"
  • toggle{"message":"Plugin ai-shield-1.0.0 disabled"}
  • reload{"message":"Plugin config reloaded"}
  • PUT /plugins/:name/sites body {"sites":[1,2]} (empty array = global)
  • /upload form field file (zip); /import-url body {"url":"https://..."}
  • /events/ws is a WebSocket stream (AES-GCM encrypted frames) — not recommended for scripts

8.11 Certificate templates cert-template

GET/openapi/v1/cert-templatesList templates
POST/openapi/v1/cert-templateCreate template
GET/openapi/v1/cert-template/:idTemplate detail
PUT/openapi/v1/cert-template/:idUpdate template
DELETE/openapi/v1/cert-template/:idDelete template
POST/openapi/v1/cert/uploadUpload to store
POST/openapi/v1/cert/reloadHot reload certs
  • POST /cert/upload: multipart/form-data with cert_file, key_file, optional name; auto-detects RSA/ECDSA/SM2
  • POST /cert/reload{"message":"Certificates reloaded"} (loads all certs into TLS engine)

8.12 WAF protocol settings waf Pro

GET/openapi/v1/waf/http3HTTP/3 status
POST/openapi/v1/waf/http3Enable/disable HTTP/3
GET/openapi/v1/waf/tls-versionsTLS versions
POST/openapi/v1/waf/tls-versionsUpdate TLS versions
POST/openapi/v1/waf/cc-challenge/generateGenerate CC challenge
POST/openapi/v1/waf/cc-challenge/verifyVerify CC challenge
GET/openapi/v1/waf/languagePanel language (public)
curl -k -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"enabled": true}' "$WAF/openapi/v1/waf/http3"
GET/openapi/v1/waf/http3{"enabled": true}
POST/openapi/v1/waf/http3{"success": true, "enabled": true, "message": "HTTP/3 enabled (UDP :443)"}
POST/openapi/v1/waf/tls-versions
Body{"versions": ["1.2","1.3"]}

8.13 Global settings settings

GET/openapi/v1/settingsGet settings
POST/openapi/v1/settingsUpdate settings
GET/openapi/v1/settings{"settings": {"base64_depth": 2, "url_depth": 2, "unicode_depth": 2, "rule_match_rate": 100}}
POST/openapi/v1/settings{"message": "Settings updated"}

8.14 Feedback feedbacks

GET/openapi/v1/feedbacksFeedback list (paginated)
PUT/openapi/v1/feedbacks/:id/statusUpdate status
DELETE/openapi/v1/feedbacksDelete feedback

8.15 Let's Encrypt letsencrypt

GET/openapi/v1/letsencrypt/alertsExpiry alerts
GET/openapi/v1/letsencrypt/listPending orders
GET/openapi/v1/letsencrypt/status/:idOrder status
GET/openapi/v1/letsencrypt/check-dns/:idCheck DNS
POST/openapi/v1/letsencrypt/orderCreate order
POST/openapi/v1/letsencrypt/saveSave certificate
POST/openapi/v1/letsencrypt/renew-orderRenew
POST/openapi/v1/letsencrypt/cancel/:idCancel order
POST/openapi/v1/letsencrypt/dismiss-alert/:idDismiss alert
curl -k -H "Authorization: Bearer $KEY" "$WAF/openapi/v1/letsencrypt/alerts"

8.16 Stats & health checks

Shares endpoints with 8.8 Monitoring and 8.4 Site health checks:

GET/openapi/v1/statsWAF global stats
GET/openapi/v1/healthAll sites health
GET/openapi/v1/health/:idSingle site health
GET/openapi/v1/realtime/wsRealtime WebSocket

8.17 Public helper endpoints (no scope / no API key)

Used for panel health checks, config bootstrap, captcha, etc. No Authorization header required.

GET/openapi/v1/pingHealth probe → pong
GET/openapi/v1/configPublic panel config
GET/openapi/v1/maintenance-server-statusMaintenance server status
GET/openapi/v1/maintenance-serverMaintenance server URL
GET/openapi/v1/captcha/challengeSlider captcha challenge
POST/openapi/v1/captcha/verifyVerify slider captcha
GET/openapi/v1/qrcodeQR code image (data URI)
curl -k "https://127.0.0.1:8088/openapi/v1/ping" # → "pong"
  • POST /captcha/verify body: {"challenge_id":"...","user_ratio":0.5,"trail":[...],"duration_ms":N}
  • Public endpoints are not audit-logged

9. Blocked endpoints

These paths are never exposed, even with *:write — returns endpoint_not_exposed (403):

PrefixReason
/openapi/v1/update/*Upgrade / restart / rollback — high risk
/openapi/v1/panel/*Panel config (port, TLS, password) — high risk
/openapi/v1/license/*License activation / migration
/openapi/v1/order*Orders (order-config, order-list, etc.)
/openapi/v1/internal/*Internal APIs
/openapi/v1/openapi/*Blocks API keys from managing keys (anti-escalation)

10. Security

Key security

  • Secret is shown in plaintext once at creation — store in a password manager immediately
  • Use separate keys per purpose (least privilege)
  • Revoke unused keys regularly
  • Never commit keys to git; use env vars or a secrets manager

Network security

  • HTTPS is required — ensure the panel has a valid certificate
  • IP allowlists on keys planned for a future release
  • Do not expose the panel port directly to the public internet

PRO license

  • OpenAPI is PRO-only; key creation and every call validate PRO status
  • After expiry, keys need not be revoked — calls return pro_required (403)
  • After renewal, all keys work immediately

Audit

  • Successful calls are audited (key prefix, path, time, source IP)
  • last_used_at is persisted every 30s to track key activity

This reference reflects the current FOXWAF release; behavior may vary by deployed version.