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.
Operations
Section titled “Operations”| Operation | Endpoint | Reference |
|---|---|---|
| Replace the complete policy | PUT /v1/policy | Set policy |
| Read compiled rules | GET /v1/policy | Get policy |
| Apply an atomic fact batch | POST /v1/facts/batch | Batch facts |
| Insert one stored fact | POST /v1/facts | Insert fact |
| Delete matching stored facts | POST /v1/facts/delete | Delete fact |
| Filter and paginate stored facts | GET /v1/facts | List facts |
| Check the policy’s authorization result | POST /v1/authorize | Authorize |
| Evaluate a predicate pattern | POST /v1/query | Query |
Values and results
Section titled “Values and results”Every fact or predicate pattern consists of a predicate name and one to three
ordered terms.
Term encoding
Section titled “Term encoding”- Identities: Represented as objects with a
PascalCasetype 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_INTEGERthroughNumber.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.
Wildcard patterns and query results
Section titled “Wildcard patterns and query results”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).
Mutations and deployment behavior
Section titled “Mutations and deployment behavior”Policy and fact writes
Section titled “Policy and fact writes”- 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 alldeletesbeforeinsertsin a single atomic transaction. - Response status and idempotency: Policy replacement, single-fact insertion
(
POST /v1/facts), and fact deletion (POST /v1/facts/delete) return HTTP204 No Content. All mutation endpoints accept an optionalIdempotency-Keyheader 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.
Revision headers across deployments
Section titled “Revision headers across deployments”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-Revisionheader representing the state revision observed by that operation. Pass that token asVerdict-Min-Revisionon 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 ignoreVerdict-Min-Revisionread headers.
Status codes and error bodies
Section titled “Status codes and error bodies”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):
| Status | Meaning |
|---|---|
| 400 | Invalid JSON, content type, body, header, query parameter, term, cursor, or revision. |
| 401 | Missing or invalid API key. |
| 403 | Instance mismatch or a write sent to a read-only Node replica. Authorization denial uses HTTP 200 with allowed: false. |
| 404 | Instance not found. |
| 408 | Request canceled in the runtime REST adapter. This is not a universal timeout response. |
| 409 | No 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. |
| 422 | Unsupported evaluation or an exhausted evaluation budget. Policy replacement instead uses this status for a compilation failure. |
| 500 | Evaluation execution failed with a JSON error, or an unexpected server error whose body may not be JSON. |
| 503 | Cloud authority unavailable or a replicated Node server not ready. The JSON error body depends on the deployment. |
Error response format
Section titled “Error response format”- Validation and operation errors: Normally return a JSON object with
errorandmessagestring fields ({"error": "...", "message": "..."}). - Cloud admission and replication errors: Can return a JSON object
containing only the
errorfield. - Unexpected server errors (
500): Can return a non-JSON body if the failure occurs outside the request handler. Check the HTTP status andContent-Typebefore assuming every failure matches the two-field JSON error schema.
Next steps
Section titled “Next steps”- Learn how to model policies and rules in Policy Fundamentals and Designing Policies.
- See how backend services connect, manage facts, and enforce decisions in Integrate with your app, Managing Facts, and Enforcing Decisions & Querying.
- Each generated operation page links to the canonical OpenAPI metadata and value schemas.