REST API reference

NetClamp’s REST API lives at http://127.0.0.1:9845/api/v1/. Every endpoint requires Authorization: Bearer <token> where token comes from C:\ProgramData\NetClamp\auth.token.

Responses are JSON; errors follow RFC 7807:

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "invalid bearer token"
}

Health & status

Method Path Description

GET

/api/v1/status

Health snapshot: version, wfp_active, kdrv_active, active_rules, monitored_apps, active_connections, total_blocked, uptime_since, competing_shapers, wfp_session_state, bfe_restarts.

GET

/api/v1/throughput?window=60

Per-second up/down samples over the trailing window.

GET

/api/v1/events

Server-Sent Events stream. Quota busts, rule sync errors, BFE bounce.

Rules

GET

/api/v1/rules

List all rules.

GET

/api/v1/rules/{id}

Get one rule.

POST

/api/v1/rules

Create. Body: rule draft.

PUT

/api/v1/rules/{id}

Update. Body: rule draft.

DELETE

/api/v1/rules/{id}

Delete.

POST

/api/v1/rules/{id}/retry

Force re-sync a broken rule.

POST

/api/v1/rules/reconcile

Reconcile every rule’s sync_state against WFP.

Rule draft schema (POST/PUT body):

{
  "name": "Block Discord",
  "app_path": "C:\\Path\\To\\app.exe",
  "action": "BLOCK",
  "direction": "BOTH",
  "remote_address": "",
  "remote_port": 0,
  "protocol": "ANY",
  "rate_limit_down_bytes_per_sec": null,
  "rate_limit_up_bytes_per_sec": null,
  "limit_scope": "PER_APP",
  "match_mode": "EXACT_PATH",
  "priority": 100,
  "enabled": true
}

Quotas

GET

/api/v1/quotas

List.

GET

/api/v1/quotas/{id}

Get one.

POST

/api/v1/quotas

Create.

PUT

/api/v1/quotas/{id}

Update.

DELETE

/api/v1/quotas/{id}

Delete.

POST

/api/v1/quotas/{id}/reset

Zero the counter.

Licensing

GET

/api/v1/license

License state: cap, used, baseline, bound credits.

GET

/api/v1/license/hwid

This machine’s HWID hash.

POST

/api/v1/license/activate

Body: {"token": "payload.signature"}.

POST

/api/v1/license/transfer/{credit_id}

Returns an unbound token to use elsewhere.

POST

/api/v1/license/rebind

Body: {"token": "unbound-token"}.

POST

/api/v1/billing/checkout

Body: {"variant_id":"…"}. Returns LS checkout URL.

GET

/api/v1/billing/check/{nonce}

Poll for mint completion after checkout. 202 pending or 200 with token.

GET

/api/v1/billing/packs

Available credit packs.

Apps & connections

GET

/api/v1/apps

Process table with cumulative up/down.

GET

/api/v1/connections

Live socket table.

GET

/api/v1/apps/{pid}

Per-process detail.

Configuration

GET

/api/v1/config

Current config.toml rendered as JSON.

PUT

/api/v1/config

Replace. Hot-reload happens automatically.

Security (auth)

POST

/api/v1/auth/rotate

Generate a new bearer token. Old token revoked.

Rule groups / subscriptions

GET

/api/v1/groups

List installed groups + subscriptions.

POST

/api/v1/groups/install

Body: bundle JSON.

POST

/api/v1/groups/subscribe

Body: {"url":"https://…","interval_sec":3600}.

DELETE

/api/v1/groups/{id}

Uninstall a group (removes its rules + quotas).

POST

/api/v1/groups/{id}/refresh

Force a subscription poll.

Status codes

200 OK

Success.

201 Created

Resource created. Location header points at it.

202 Accepted

Operation queued; check the SSE stream or a /check/…​ endpoint.

400 Bad Request

Validation error. detail has the field-level reason.

401 Unauthorized

Missing or invalid bearer token.

404 Not Found

Resource doesn’t exist.

409 Conflict

Sync conflict (rule edited concurrently). Retry after reading current state.

429 Too Many Requests

Rate limit on a billing endpoint. Honor Retry-After.

500 Internal Server Error

Unexpected. Captured in service.log.

503 Service Unavailable

WFP session torn down by BFE bounce — see Troubleshooting.