curl --request POST \
--url https://api.checkfu.com/v1/action-policies/evaluate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'checkfu-version: <checkfu-version>' \
--data '
{
"subject": {
"kind": "principal",
"principal": "<string>"
},
"resource": {
"id": "<string>"
},
"context": {
"requested_by": {
"kind": "principal",
"principal": "<string>"
},
"acted_as": "<string>",
"surface_scope_id": "<string>"
}
}
'import requests
url = "https://api.checkfu.com/v1/action-policies/evaluate"
payload = {
"subject": {
"kind": "principal",
"principal": "<string>"
},
"resource": { "id": "<string>" },
"context": {
"requested_by": {
"kind": "principal",
"principal": "<string>"
},
"acted_as": "<string>",
"surface_scope_id": "<string>"
}
}
headers = {
"checkfu-version": "<checkfu-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'checkfu-version': '<checkfu-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
subject: {kind: 'principal', principal: '<string>'},
resource: {id: '<string>'},
context: {
requested_by: {kind: 'principal', principal: '<string>'},
acted_as: '<string>',
surface_scope_id: '<string>'
}
})
};
fetch('https://api.checkfu.com/v1/action-policies/evaluate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.checkfu.com/v1/action-policies/evaluate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'subject' => [
'kind' => 'principal',
'principal' => '<string>'
],
'resource' => [
'id' => '<string>'
],
'context' => [
'requested_by' => [
'kind' => 'principal',
'principal' => '<string>'
],
'acted_as' => '<string>',
'surface_scope_id' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"checkfu-version: <checkfu-version>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.checkfu.com/v1/action-policies/evaluate"
payload := strings.NewReader("{\n \"subject\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"resource\": {\n \"id\": \"<string>\"\n },\n \"context\": {\n \"requested_by\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"acted_as\": \"<string>\",\n \"surface_scope_id\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("checkfu-version", "<checkfu-version>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.checkfu.com/v1/action-policies/evaluate")
.header("checkfu-version", "<checkfu-version>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"subject\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"resource\": {\n \"id\": \"<string>\"\n },\n \"context\": {\n \"requested_by\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"acted_as\": \"<string>\",\n \"surface_scope_id\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.checkfu.com/v1/action-policies/evaluate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["checkfu-version"] = '<checkfu-version>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"subject\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"resource\": {\n \"id\": \"<string>\"\n },\n \"context\": {\n \"requested_by\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"acted_as\": \"<string>\",\n \"surface_scope_id\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"disposition": "allow",
"reason": "no_matching_permission_assignment",
"permission_assignment_ids": [
"<string>"
],
"matched_action_policy_rules": [
{
"action_policy_id": "<string>",
"rule_id": "<string>",
"effect": "allow"
}
]
}{
"error": {
"type": "validation.malformed",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#validation-malformed"
}
}{
"error": {
"type": "auth.invalid_key",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#auth-invalid-key"
}
}{
"error": {
"type": "auth.disabled_tenancy",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#auth-disabled-tenancy"
}
}{
"error": {
"type": "validation.idempotency_conflict",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#validation-idempotency-conflict"
}
}{
"error": {
"type": "budget.exceeded",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#budget-exceeded"
}
}{
"error": {
"type": "runtime.internal",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#runtime-internal"
}
}Check a governance decision
Evaluate one subject, resource, and permission against the Workspace’s PermissionAssignments and active ActionPolicies without performing the requested action, while appending the durable governance.checked audit fact. Accepts an optional Idempotency-Key; a keyed retry recovers the exact audited decision without appending another fact, even if governance authority changed after response loss. Returns the disposition (allow, require_approval, or deny), the reason, the matching PermissionAssignment ids, and the matching ActionPolicy rules. No matching PermissionAssignment denies outright and never consults ActionPolicy; with a PermissionAssignment, the strongest matching active rule wins, ordered allow < require_approval < deny. Use it to preflight a plan or a UI instead of discovering a denial mid-Run.
Checkfu support posture: alpha; hosted. Required evidence journey: governance-registry. Deployment-specific readiness and the latest proven release are available from GET /v1/support/capabilities.
curl --request POST \
--url https://api.checkfu.com/v1/action-policies/evaluate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'checkfu-version: <checkfu-version>' \
--data '
{
"subject": {
"kind": "principal",
"principal": "<string>"
},
"resource": {
"id": "<string>"
},
"context": {
"requested_by": {
"kind": "principal",
"principal": "<string>"
},
"acted_as": "<string>",
"surface_scope_id": "<string>"
}
}
'import requests
url = "https://api.checkfu.com/v1/action-policies/evaluate"
payload = {
"subject": {
"kind": "principal",
"principal": "<string>"
},
"resource": { "id": "<string>" },
"context": {
"requested_by": {
"kind": "principal",
"principal": "<string>"
},
"acted_as": "<string>",
"surface_scope_id": "<string>"
}
}
headers = {
"checkfu-version": "<checkfu-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'checkfu-version': '<checkfu-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
subject: {kind: 'principal', principal: '<string>'},
resource: {id: '<string>'},
context: {
requested_by: {kind: 'principal', principal: '<string>'},
acted_as: '<string>',
surface_scope_id: '<string>'
}
})
};
fetch('https://api.checkfu.com/v1/action-policies/evaluate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.checkfu.com/v1/action-policies/evaluate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'subject' => [
'kind' => 'principal',
'principal' => '<string>'
],
'resource' => [
'id' => '<string>'
],
'context' => [
'requested_by' => [
'kind' => 'principal',
'principal' => '<string>'
],
'acted_as' => '<string>',
'surface_scope_id' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"checkfu-version: <checkfu-version>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.checkfu.com/v1/action-policies/evaluate"
payload := strings.NewReader("{\n \"subject\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"resource\": {\n \"id\": \"<string>\"\n },\n \"context\": {\n \"requested_by\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"acted_as\": \"<string>\",\n \"surface_scope_id\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("checkfu-version", "<checkfu-version>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.checkfu.com/v1/action-policies/evaluate")
.header("checkfu-version", "<checkfu-version>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"subject\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"resource\": {\n \"id\": \"<string>\"\n },\n \"context\": {\n \"requested_by\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"acted_as\": \"<string>\",\n \"surface_scope_id\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.checkfu.com/v1/action-policies/evaluate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["checkfu-version"] = '<checkfu-version>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"subject\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"resource\": {\n \"id\": \"<string>\"\n },\n \"context\": {\n \"requested_by\": {\n \"kind\": \"principal\",\n \"principal\": \"<string>\"\n },\n \"acted_as\": \"<string>\",\n \"surface_scope_id\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"disposition": "allow",
"reason": "no_matching_permission_assignment",
"permission_assignment_ids": [
"<string>"
],
"matched_action_policy_rules": [
{
"action_policy_id": "<string>",
"rule_id": "<string>",
"effect": "allow"
}
]
}{
"error": {
"type": "validation.malformed",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#validation-malformed"
}
}{
"error": {
"type": "auth.invalid_key",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#auth-invalid-key"
}
}{
"error": {
"type": "auth.disabled_tenancy",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#auth-disabled-tenancy"
}
}{
"error": {
"type": "validation.idempotency_conflict",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#validation-idempotency-conflict"
}
}{
"error": {
"type": "budget.exceeded",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#budget-exceeded"
}
}{
"error": {
"type": "runtime.internal",
"message": "<string>",
"more": "https://docs.checkfu.com/reference/errors#runtime-internal"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
2026-08-27 255Body
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
- Option 6
Show child attributes
Show child attributes
Show child attributes
Show child attributes
read, write, use, invoke, steer, observe, approve, edit, view, act_as, use_agent, use_connection, use_tool, use_memory, use_model, use_harness, use_environment, publish_artifact, create_routine, manage_routine Show child attributes
Show child attributes
Response
Success
allow, require_approval, deny no_matching_permission_assignment, permission_assignment_allows, action_policy_allows, action_policy_requires_approval, action_policy_denies, permission_assignment_expired, permission_assignment_not_yet_active ^perm_[0-9a-f]{32}$Show child attributes
Show child attributes