Skip to content

HTTP API Reference

munio exposes a REST API for language-agnostic tool call verification.

Terminal window
pip install "munio[server]"
munio serve --pack generic --pack openclaw --port 8080

All endpoints are under the /v1/ prefix for API versioning.

Health check for load balancers and k8s probes.

Terminal window
curl http://localhost:8080/v1/health

Response (200):

{
"status": "ok",
"version": "0.1.0",
"constraint_count": 18
}

List available constraint packs with constraint counts.

Terminal window
curl http://localhost:8080/v1/packs

Response (200):

{
"packs": {
"generic": 7,
"openclaw": 11
}
}

Universal action verification endpoint.

Terminal window
curl -X POST http://localhost:8080/v1/verify \
-H "Content-Type: application/json" \
-d '{"tool":"exec","args":{"command":"rm -rf /"},"constraints":"openclaw"}'

Request:

{
"tool": "exec",
"args": {"command": "rm -rf /"},
"agent_id": "agent-1",
"metadata": {},
"constraints": "openclaw",
"mode": "enforce"
}
FieldTypeRequiredDescription
toolstringyesTool name
argsobjectnoTool call arguments (default: {})
agent_idstringnoAgent identifier
metadataobjectnoAdditional metadata
constraintsstringnoPack name override (default: server’s default packs)
modestringnoIgnored (mode is server-side config only — mode override removed for security)

Response (200): Full VerificationResult JSON:

{
"allowed": false,
"mode": "enforce",
"violations": [
{
"constraint_name": "openclaw-exec-command-denylist",
"constraint_category": "ASI02",
"severity": "critical",
"message": "Field 'command' matched denied pattern: rm\\s+(-[a-zA-Z]*f...",
"field": "command",
"actual_value": "rm -rf /",
"tier": 1
}
],
"checked_constraints": 3,
"elapsed_ms": 0.234,
"tier_breakdown": {"tier_1": 3}
}

OpenClaw-native endpoint matching the before_tool_call hook format exactly.

Terminal window
curl -X POST http://localhost:8080/v1/openclaw/before-tool-call \
-H "Content-Type: application/json" \
-d '{"event":{"toolName":"exec","params":{"command":"ls -la"}},"ctx":{"toolName":"exec","agentId":"agent-1"}}'

Request:

{
"event": {
"toolName": "exec",
"params": {"command": "ls -la"}
},
"ctx": {
"toolName": "exec",
"agentId": "agent-1",
"sessionKey": "sess-abc"
}
}

Response (200):

{
"block": false,
"blockReason": null
}

Or when blocked:

{
"block": true,
"blockReason": "Field 'command' matched denied pattern"
}
StatusErrorWhen
400Pack not foundUnknown constraint pack name
413payload_too_largeRequest body exceeds 1MB
422Validation errorMissing/invalid fields (Pydantic)
422verification_errorInternal verification error
500internal_errorUnexpected server error

All request models use extra="ignore" — unknown fields are silently discarded. This means:

  • Future OpenClaw versions can add new fields to hook events without breaking the plugin
  • Clients can send extra metadata without causing 422 errors
  • Bind address: Default 127.0.0.1 (localhost only). For network deployment, use a reverse proxy with authentication.
  • CORS: Configurable via --cors-origins. Default is empty (no cross-origin access).
  • Request size: 1MB limit on request bodies.
  • Pack names: Validated against ^[a-z0-9][a-z0-9_-]*$ regex — no path traversal.
  • No auth in v1: Authentication should be handled by your reverse proxy (nginx, Caddy, etc.).