REST API

Clearplane exposes its public management API below https://<management-host>/api/. The generated OpenAPI 3.1 contract is available to users with Settings.Read at:

GET https://<management-host>/api/openapi

The contract is generated from the running controllers and shared JSON configuration. It is the source of truth for paths, methods, request and response shapes, nullability, and enum values. Schema descriptions state conditional requirements that cannot be expressed as a single required-property list; the API applies those rules with FluentValidation and returns 400 for violations.

Authentication and permissions

Sign in with a cookie jar, then reuse that jar for API requests:

base='https://clearplane.example.com/api'

curl --fail-with-body \
  --cookie-jar clearplane.cookies \
  --header 'Content-Type: application/json' \
  --data '{"userName":"Administrator","password":"replace-me"}' \
  "$base/authentication/sign-in"

curl --fail-with-body \
  --cookie clearplane.cookies \
  "$base/openapi"

The sign-in response's nextStep is SessionCreated when authentication is complete. MultiFactorChallengeRequired means the client must complete the authentication/multi-factor-authentication operation described by the contract before using protected operations.

For POST, PUT, PATCH, or DELETE with the session cookie, also send the browser-session CSRF header:

X-Clearplane-CSRF: Clearplane.Browser

Each operation enforces its own permission. A missing or invalid session returns 401; an authenticated account without the required permission returns 403. Every protected OpenAPI operation declares the clearplaneSession security scheme and its exact permission in x-clearplane-permissions; unsafe operations also declare clearplaneCsrf. The OpenAPI document itself requires Settings.Read.

JSON and updates

  • Property names use camel case.
  • Route path values are complete route patterns on every surface. /api matches only that literal path, while /api/{**catch-all} matches /api, /api/orders, and everything below it. Docker labels use the same value under clearplane.proxy.path or clearplane.redirect.path; Clearplane does not rewrite it.
  • Optional stripPrefix and pathRewrite values treat an empty or whitespace-only string as unset, matching blank label and UI values.
  • Durations use integer fields whose names state the unit, such as activityTimeoutSeconds, windowSeconds, banDurationSeconds, preflightMaxAgeSeconds, and defaultTimeToLiveSeconds. The API does not expose the internal TimeSpan property names without a unit.
  • Enum values use the canonical member names listed by the contract, such as MaxMind or Detection. Input matching is case-insensitive, but numeric enum backing values are rejected.
  • Treat PUT request models as complete replacements. Read the current resource first and preserve fields that should not change.
  • Authentication-policy passwords and JWT signing-key material are write-only and are returned as empty strings. On update, leave an existing credential password or signing key blank to preserve its stored value. A blank value cannot create a new credential or key, change its identity or kind, or survive an authentication-type change; supply new material in those cases.
  • Validation and malformed JSON return 400. Missing resources return 404. Ownership, stale state, or another in-progress mutation can return 409; read the response body for the specific conflict.
  • Setting responses distinguish saved and effective values and report their effective source where applicable. The configuration catalog states whether a change is immediate, validated, staged until Edge apply, or restart-required.

Automatic-apply settings are read with GET /api/edge/automatic-apply under Settings.Read and changed with PUT /api/edge/automatic-apply under Settings.Write. Operational Edge statistics remain under Services.Read and do not expose configuration settings.

For example, a rate-limit request uses a numeric seconds field:

{
  "name": "login-burst",
  "windowSeconds": 60,
  "requestLimit": 20
}

Core converts windowSeconds: 60 to its typed duration and persists that duration in the Window database field. Responses convert it back to windowSeconds: 60; clients never need to know the database representation.

Configuration ownership

The API updates the same saved value that the UI edits. Resolution remains environment variable → validated Clearplane container label → saved UI value → built-in default.

A runtime label on a Clearplane-owned container overrides the matching saved field. The UI presents that field as read-only, and the API response reports the effective source. Removing the label reveals the saved UI value again.

Resources discovered from application-container labels are container-managed. Change their labels instead of trying to mutate the generated route or inline policies through the API; conflicting mutations return 409. UI/API-created resources remain editable through the API subject to permissions and normal reference checks.

Use the Docker label reference for label parsing and ownership rules, and the environment variable reference for bootstrap and secret handling.