Skip to content

REST API reference

The Verdict REST API exposes /v1 HTTP endpoints for replacing policies, mutating and listing stored facts, checking authorization decisions, and evaluating predicate queries.

All endpoint paths are relative to your instance URL: either a standalone Node server origin (such as http://localhost:4891) or a Cloud instance URL ending in /instances/<organization>/<instance>. Control-plane APIs, Connect RPC, and PostgreSQL runtimes are outside the scope of this reference.

Cloud instances and Node servers configured with API keys require a bearer token in the Authorization header. For a local Node server started without API keys, omit the Authorization header:

curl "$VERDICT_INSTANCE_URL/v1/authorize" \
-H "Authorization: Bearer $VERDICT_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"actor":{"type":"User","id":"alice"},"action":"read","resource":{"type":"Document","id":"handbook"}}'

Publish a policy to the instance before calling /v1/authorize. If you are used to HTTP APIs returning 403 Forbidden when a user lacks permission, note that /v1/authorize is a query about your policy: both allowed and denied decisions return HTTP 200 OK with {"allowed": true} or {"allowed": false}. HTTP 403 indicates that the HTTP request itself is not permitted to access or mutate the Verdict instance.

OperationEndpointReference
Replace the complete policyPUT /v1/policySet policy
Read compiled rulesGET /v1/policyGet policy
Apply an atomic fact batchPOST /v1/facts/batchBatch facts
Insert one stored factPOST /v1/factsInsert fact
Delete matching stored factsPOST /v1/facts/deleteDelete fact
Filter and paginate stored factsGET /v1/factsList facts
Check the policy’s authorization resultPOST /v1/authorizeAuthorize
Evaluate a predicate patternPOST /v1/queryQuery

Every fact or predicate pattern consists of a predicate name and one to three ordered terms.

  • Identities: Represented as objects with a PascalCase type and string ID, such as {"type": "User", "id": "alice"} or {"type": "Document", "id": "handbook"}.
  • Strings and booleans: Encoded as standard JSON strings ("read") and booleans (true, false).
  • 64-bit integers: Plain JSON numbers must be safe integers (Number.MIN_SAFE_INTEGER through Number.MAX_SAFE_INTEGER). For signed 64-bit integers outside the safe range, pass {"type": "int64", "value": "9223372036854775807"}. Responses use the same tagged object form whenever an integer exceeds the safe JSON number range.

Query (POST /v1/query) and deletion (POST /v1/facts/delete) patterns accept null or {"wildcard": {}} in any term position to match any value. A wildcard object can also specify an identity type constraint or a name; repeating the same wildcard name across positions requires those positions to bind to the same typed value.

POST /v1/query evaluates your policy rules and returns a results array where each row contains the bound values for the request’s wildcard positions in order:

  • When a pattern includes wildcards, each matching row contains one value per wildcard position.
  • When a pattern is fully bound (zero wildcards), a match returns one empty row ({"results": [[]]}), while no match returns an empty list ({"results": []}).

Unlike POST /v1/query, which evaluates policy rules to return derived answers, GET /v1/facts returns only stored facts (including concrete facts declared in the active policy file).

  • Policy replacement (PUT /v1/policy): Replaces the active rules and any facts declared inside the policy file while preserving facts inserted through the API.
  • Atomic batches (POST /v1/facts/batch): Applies all deletes before inserts in a single atomic transaction.
  • Response status and idempotency: Policy replacement, single-fact insertion (POST /v1/facts), and fact deletion (POST /v1/facts/delete) return HTTP 204 No Content. All mutation endpoints accept an optional Idempotency-Key header so you can safely retry the same request payload within the key’s retention window. See the individual operation pages for replay and conflict details.

Raw HTTP requests are stateless: the REST API does not automatically track a client session or retry failed requests.

How read consistency works after a write depends on your deployment topology:

  • Cloud and replicated Node deployments: Responses can include a Verdict-Revision header representing the state revision observed by that operation. Pass that token as Verdict-Min-Revision on subsequent read requests (authorize, query, list-facts, get-policy) when a replica must be caught up to at least that write before answering.
  • Standalone Node servers (verdict serve): All reads and writes execute against a single local store, so standalone servers are immediately consistent and ignore Verdict-Min-Revision read headers.

Individual operation pages list their success statuses and any endpoint-specific exceptions. The table below summarizes the common error status codes across operations and deployments (not every deployment returns every status for every endpoint):

StatusMeaning
400Invalid JSON, content type, body, header, query parameter, term, cursor, or revision.
401Missing or invalid API key.
403Instance mismatch or a write sent to a read-only Node replica. Authorization denial uses HTTP 200 with allowed: false.
404Instance not found.
408Request canceled in the runtime REST adapter. This is not a universal timeout response.
409No policy when one is required, an idempotency key conflict for a mutation, a closed runtime, or a deployment consistency conflict. Operation pages may specify a narrower set of conditions.
422Unsupported evaluation or an exhausted evaluation budget. Policy replacement instead uses this status for a compilation failure.
500Evaluation execution failed with a JSON error, or an unexpected server error whose body may not be JSON.
503Cloud authority unavailable or a replicated Node server not ready. The JSON error body depends on the deployment.
  • Validation and operation errors: Normally return a JSON object with error and message string fields ({"error": "...", "message": "..."}).
  • Cloud admission and replication errors: Can return a JSON object containing only the error field.
  • Unexpected server errors (500): Can return a non-JSON body if the failure occurs outside the request handler. Check the HTTP status and Content-Type before assuming every failure matches the two-field JSON error schema.