curl --request POST \
--url https://api.scrip.dev/v1/rules/validate \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data @- <<EOF
{
"condition": "event.type == 'purchase' && event.amount > 100",
"actions": [
{
"allow_negative": false,
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"bucket": "AVAILABLE",
"delay": "24h",
"description": "Purchase reward",
"event_name": "check_status",
"expires_at": "365d",
"key": "purchase_count",
"level": "gold",
"matures_at": "30d",
"payload": {},
"reference_id": "${{ event.authorization_id }}",
"reset_after": "30d",
"tag": "VIP",
"target": {
"external_id": "${{ event.referrer_id }}",
"id": "550e8400-e29b-41d4-a716-446655440000",
"participant_id": "${{ event.recipient_id }}",
"type": "PARTICIPANT"
},
"tier": "status",
"type": "CREDIT",
"value": "1"
}
],
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"rule_id": "550e8400-e29b-41d4-a716-446655440002"
}
EOFimport requests
url = "https://api.scrip.dev/v1/rules/validate"
payload = {
"condition": "event.type == 'purchase' && event.amount > 100",
"actions": [
{
"allow_negative": False,
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"bucket": "AVAILABLE",
"delay": "24h",
"description": "Purchase reward",
"event_name": "check_status",
"expires_at": "365d",
"key": "purchase_count",
"level": "gold",
"matures_at": "30d",
"payload": {},
"reference_id": "${{ event.authorization_id }}",
"reset_after": "30d",
"tag": "VIP",
"target": {
"external_id": "${{ event.referrer_id }}",
"id": "550e8400-e29b-41d4-a716-446655440000",
"participant_id": "${{ event.recipient_id }}",
"type": "PARTICIPANT"
},
"tier": "status",
"type": "CREDIT",
"value": "1"
}
],
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"rule_id": "550e8400-e29b-41d4-a716-446655440002"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
condition: 'event.type == \'purchase\' && event.amount > 100',
actions: [
{
allow_negative: false,
amount: '${{ event.amount * 0.03 }}',
asset_id: '550e8400-e29b-41d4-a716-446655440000',
bucket: 'AVAILABLE',
delay: '24h',
description: 'Purchase reward',
event_name: 'check_status',
expires_at: '365d',
key: 'purchase_count',
level: 'gold',
matures_at: '30d',
payload: {},
reference_id: '${{ event.authorization_id }}',
reset_after: '30d',
tag: 'VIP',
target: {
external_id: '${{ event.referrer_id }}',
id: '550e8400-e29b-41d4-a716-446655440000',
participant_id: '${{ event.recipient_id }}',
type: 'PARTICIPANT'
},
tier: 'status',
type: 'CREDIT',
value: '1'
}
],
program_id: '550e8400-e29b-41d4-a716-446655440001',
rule_id: '550e8400-e29b-41d4-a716-446655440002'
})
};
fetch('https://api.scrip.dev/v1/rules/validate', 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.scrip.dev/v1/rules/validate",
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([
'condition' => 'event.type == \'purchase\' && event.amount > 100',
'actions' => [
[
'allow_negative' => false,
'amount' => '${{ event.amount * 0.03 }}',
'asset_id' => '550e8400-e29b-41d4-a716-446655440000',
'bucket' => 'AVAILABLE',
'delay' => '24h',
'description' => 'Purchase reward',
'event_name' => 'check_status',
'expires_at' => '365d',
'key' => 'purchase_count',
'level' => 'gold',
'matures_at' => '30d',
'payload' => [
],
'reference_id' => '${{ event.authorization_id }}',
'reset_after' => '30d',
'tag' => 'VIP',
'target' => [
'external_id' => '${{ event.referrer_id }}',
'id' => '550e8400-e29b-41d4-a716-446655440000',
'participant_id' => '${{ event.recipient_id }}',
'type' => 'PARTICIPANT'
],
'tier' => 'status',
'type' => 'CREDIT',
'value' => '1'
]
],
'program_id' => '550e8400-e29b-41d4-a716-446655440001',
'rule_id' => '550e8400-e29b-41d4-a716-446655440002'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.scrip.dev/v1/rules/validate"
payload := strings.NewReader("{\n \"condition\": \"event.type == 'purchase' && event.amount > 100\",\n \"actions\": [\n {\n \"allow_negative\": false,\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"bucket\": \"AVAILABLE\",\n \"delay\": \"24h\",\n \"description\": \"Purchase reward\",\n \"event_name\": \"check_status\",\n \"expires_at\": \"365d\",\n \"key\": \"purchase_count\",\n \"level\": \"gold\",\n \"matures_at\": \"30d\",\n \"payload\": {},\n \"reference_id\": \"${{ event.authorization_id }}\",\n \"reset_after\": \"30d\",\n \"tag\": \"VIP\",\n \"target\": {\n \"external_id\": \"${{ event.referrer_id }}\",\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"participant_id\": \"${{ event.recipient_id }}\",\n \"type\": \"PARTICIPANT\"\n },\n \"tier\": \"status\",\n \"type\": \"CREDIT\",\n \"value\": \"1\"\n }\n ],\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"rule_id\": \"550e8400-e29b-41d4-a716-446655440002\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.scrip.dev/v1/rules/validate")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"condition\": \"event.type == 'purchase' && event.amount > 100\",\n \"actions\": [\n {\n \"allow_negative\": false,\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"bucket\": \"AVAILABLE\",\n \"delay\": \"24h\",\n \"description\": \"Purchase reward\",\n \"event_name\": \"check_status\",\n \"expires_at\": \"365d\",\n \"key\": \"purchase_count\",\n \"level\": \"gold\",\n \"matures_at\": \"30d\",\n \"payload\": {},\n \"reference_id\": \"${{ event.authorization_id }}\",\n \"reset_after\": \"30d\",\n \"tag\": \"VIP\",\n \"target\": {\n \"external_id\": \"${{ event.referrer_id }}\",\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"participant_id\": \"${{ event.recipient_id }}\",\n \"type\": \"PARTICIPANT\"\n },\n \"tier\": \"status\",\n \"type\": \"CREDIT\",\n \"value\": \"1\"\n }\n ],\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"rule_id\": \"550e8400-e29b-41d4-a716-446655440002\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/rules/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"condition\": \"event.type == 'purchase' && event.amount > 100\",\n \"actions\": [\n {\n \"allow_negative\": false,\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"bucket\": \"AVAILABLE\",\n \"delay\": \"24h\",\n \"description\": \"Purchase reward\",\n \"event_name\": \"check_status\",\n \"expires_at\": \"365d\",\n \"key\": \"purchase_count\",\n \"level\": \"gold\",\n \"matures_at\": \"30d\",\n \"payload\": {},\n \"reference_id\": \"${{ event.authorization_id }}\",\n \"reset_after\": \"30d\",\n \"tag\": \"VIP\",\n \"target\": {\n \"external_id\": \"${{ event.referrer_id }}\",\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"participant_id\": \"${{ event.recipient_id }}\",\n \"type\": \"PARTICIPANT\"\n },\n \"tier\": \"status\",\n \"type\": \"CREDIT\",\n \"value\": \"1\"\n }\n ],\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"rule_id\": \"550e8400-e29b-41d4-a716-446655440002\"\n}"
response = http.request(request)
puts response.read_body{
"message": "CEL condition is valid",
"note": "Validation checks syntax only. Field references are not verified against an event schema.",
"valid": true,
"warnings": [
{
"code": "unknown_state_key",
"key": "purchaseCnt",
"kind": "counter",
"message": "unknown counter \"purchaseCnt\" — no rule in this program writes it; did you mean \"purchase_count\"?",
"scope": "participant",
"suggestion": "purchase_count"
}
]
}{
"code": "bad_request",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Missing or invalid credentials"
}{
"code": "forbidden",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Insufficient permissions for this action"
}{
"code": "unsupported_media_type",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Content-Type must be application/json"
}{
"code": "internal_error",
"message": "An internal error occurred"
}Validate a CEL condition
Check whether a CEL expression is syntactically valid without creating a rule.
curl --request POST \
--url https://api.scrip.dev/v1/rules/validate \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data @- <<EOF
{
"condition": "event.type == 'purchase' && event.amount > 100",
"actions": [
{
"allow_negative": false,
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"bucket": "AVAILABLE",
"delay": "24h",
"description": "Purchase reward",
"event_name": "check_status",
"expires_at": "365d",
"key": "purchase_count",
"level": "gold",
"matures_at": "30d",
"payload": {},
"reference_id": "${{ event.authorization_id }}",
"reset_after": "30d",
"tag": "VIP",
"target": {
"external_id": "${{ event.referrer_id }}",
"id": "550e8400-e29b-41d4-a716-446655440000",
"participant_id": "${{ event.recipient_id }}",
"type": "PARTICIPANT"
},
"tier": "status",
"type": "CREDIT",
"value": "1"
}
],
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"rule_id": "550e8400-e29b-41d4-a716-446655440002"
}
EOFimport requests
url = "https://api.scrip.dev/v1/rules/validate"
payload = {
"condition": "event.type == 'purchase' && event.amount > 100",
"actions": [
{
"allow_negative": False,
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"bucket": "AVAILABLE",
"delay": "24h",
"description": "Purchase reward",
"event_name": "check_status",
"expires_at": "365d",
"key": "purchase_count",
"level": "gold",
"matures_at": "30d",
"payload": {},
"reference_id": "${{ event.authorization_id }}",
"reset_after": "30d",
"tag": "VIP",
"target": {
"external_id": "${{ event.referrer_id }}",
"id": "550e8400-e29b-41d4-a716-446655440000",
"participant_id": "${{ event.recipient_id }}",
"type": "PARTICIPANT"
},
"tier": "status",
"type": "CREDIT",
"value": "1"
}
],
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"rule_id": "550e8400-e29b-41d4-a716-446655440002"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
condition: 'event.type == \'purchase\' && event.amount > 100',
actions: [
{
allow_negative: false,
amount: '${{ event.amount * 0.03 }}',
asset_id: '550e8400-e29b-41d4-a716-446655440000',
bucket: 'AVAILABLE',
delay: '24h',
description: 'Purchase reward',
event_name: 'check_status',
expires_at: '365d',
key: 'purchase_count',
level: 'gold',
matures_at: '30d',
payload: {},
reference_id: '${{ event.authorization_id }}',
reset_after: '30d',
tag: 'VIP',
target: {
external_id: '${{ event.referrer_id }}',
id: '550e8400-e29b-41d4-a716-446655440000',
participant_id: '${{ event.recipient_id }}',
type: 'PARTICIPANT'
},
tier: 'status',
type: 'CREDIT',
value: '1'
}
],
program_id: '550e8400-e29b-41d4-a716-446655440001',
rule_id: '550e8400-e29b-41d4-a716-446655440002'
})
};
fetch('https://api.scrip.dev/v1/rules/validate', 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.scrip.dev/v1/rules/validate",
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([
'condition' => 'event.type == \'purchase\' && event.amount > 100',
'actions' => [
[
'allow_negative' => false,
'amount' => '${{ event.amount * 0.03 }}',
'asset_id' => '550e8400-e29b-41d4-a716-446655440000',
'bucket' => 'AVAILABLE',
'delay' => '24h',
'description' => 'Purchase reward',
'event_name' => 'check_status',
'expires_at' => '365d',
'key' => 'purchase_count',
'level' => 'gold',
'matures_at' => '30d',
'payload' => [
],
'reference_id' => '${{ event.authorization_id }}',
'reset_after' => '30d',
'tag' => 'VIP',
'target' => [
'external_id' => '${{ event.referrer_id }}',
'id' => '550e8400-e29b-41d4-a716-446655440000',
'participant_id' => '${{ event.recipient_id }}',
'type' => 'PARTICIPANT'
],
'tier' => 'status',
'type' => 'CREDIT',
'value' => '1'
]
],
'program_id' => '550e8400-e29b-41d4-a716-446655440001',
'rule_id' => '550e8400-e29b-41d4-a716-446655440002'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.scrip.dev/v1/rules/validate"
payload := strings.NewReader("{\n \"condition\": \"event.type == 'purchase' && event.amount > 100\",\n \"actions\": [\n {\n \"allow_negative\": false,\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"bucket\": \"AVAILABLE\",\n \"delay\": \"24h\",\n \"description\": \"Purchase reward\",\n \"event_name\": \"check_status\",\n \"expires_at\": \"365d\",\n \"key\": \"purchase_count\",\n \"level\": \"gold\",\n \"matures_at\": \"30d\",\n \"payload\": {},\n \"reference_id\": \"${{ event.authorization_id }}\",\n \"reset_after\": \"30d\",\n \"tag\": \"VIP\",\n \"target\": {\n \"external_id\": \"${{ event.referrer_id }}\",\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"participant_id\": \"${{ event.recipient_id }}\",\n \"type\": \"PARTICIPANT\"\n },\n \"tier\": \"status\",\n \"type\": \"CREDIT\",\n \"value\": \"1\"\n }\n ],\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"rule_id\": \"550e8400-e29b-41d4-a716-446655440002\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.scrip.dev/v1/rules/validate")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"condition\": \"event.type == 'purchase' && event.amount > 100\",\n \"actions\": [\n {\n \"allow_negative\": false,\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"bucket\": \"AVAILABLE\",\n \"delay\": \"24h\",\n \"description\": \"Purchase reward\",\n \"event_name\": \"check_status\",\n \"expires_at\": \"365d\",\n \"key\": \"purchase_count\",\n \"level\": \"gold\",\n \"matures_at\": \"30d\",\n \"payload\": {},\n \"reference_id\": \"${{ event.authorization_id }}\",\n \"reset_after\": \"30d\",\n \"tag\": \"VIP\",\n \"target\": {\n \"external_id\": \"${{ event.referrer_id }}\",\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"participant_id\": \"${{ event.recipient_id }}\",\n \"type\": \"PARTICIPANT\"\n },\n \"tier\": \"status\",\n \"type\": \"CREDIT\",\n \"value\": \"1\"\n }\n ],\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"rule_id\": \"550e8400-e29b-41d4-a716-446655440002\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/rules/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"condition\": \"event.type == 'purchase' && event.amount > 100\",\n \"actions\": [\n {\n \"allow_negative\": false,\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"bucket\": \"AVAILABLE\",\n \"delay\": \"24h\",\n \"description\": \"Purchase reward\",\n \"event_name\": \"check_status\",\n \"expires_at\": \"365d\",\n \"key\": \"purchase_count\",\n \"level\": \"gold\",\n \"matures_at\": \"30d\",\n \"payload\": {},\n \"reference_id\": \"${{ event.authorization_id }}\",\n \"reset_after\": \"30d\",\n \"tag\": \"VIP\",\n \"target\": {\n \"external_id\": \"${{ event.referrer_id }}\",\n \"id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"participant_id\": \"${{ event.recipient_id }}\",\n \"type\": \"PARTICIPANT\"\n },\n \"tier\": \"status\",\n \"type\": \"CREDIT\",\n \"value\": \"1\"\n }\n ],\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"rule_id\": \"550e8400-e29b-41d4-a716-446655440002\"\n}"
response = http.request(request)
puts response.read_body{
"message": "CEL condition is valid",
"note": "Validation checks syntax only. Field references are not verified against an event schema.",
"valid": true,
"warnings": [
{
"code": "unknown_state_key",
"key": "purchaseCnt",
"kind": "counter",
"message": "unknown counter \"purchaseCnt\" — no rule in this program writes it; did you mean \"purchase_count\"?",
"scope": "participant",
"suggestion": "purchase_count"
}
]
}{
"code": "bad_request",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Missing or invalid credentials"
}{
"code": "forbidden",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Insufficient permissions for this action"
}{
"code": "unsupported_media_type",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Content-Type must be application/json"
}{
"code": "internal_error",
"message": "An internal error occurred"
}condition string in the request body. The response returns a valid boolean and a message with details.
Pass an optional program_id to validate references against a specific program: tier keys and asset symbols in the expression are checked against that program’s configuration, and the response includes non-blocking vocabulary warnings. Pass an optional draft actions array to run the same checks on action expressions (template syntax, CEL compilation, references) before creating the rule.
Field references to event.* are never validated because events are schemaless. For example, event.amount > 100 passes even if your events never include an amount field. Use the simulate endpoint to test a rule against realistic data.
Authorizations
API key passed in the X-API-Key header.
Body
Condition to validate
CEL expression to validate
1"event.type == 'purchase' && event.amount > 100"
Optional draft actions. When supplied alongside program_id, the keys these actions write count as known vocabulary, so a condition that reads a key the same rule writes does not warn. Used for accurate live validation before the rule is saved; only the action keys/targets are read (no full validation).
Show child attributes
Show child attributes
Optional program ID. When supplied, the condition is also checked against the program: tier key references (participant.tiers.) are validated, and counter/tag/attribute key references that no rule in the program writes produce non-blocking warnings. Without it, only tier fields, participant roots, and deprecation advisories are checked.
"550e8400-e29b-41d4-a716-446655440001"
Optional ID of the rule being edited. When validating an edit, pass it so the rule's own persisted actions are excluded from the program vocabulary (the stale copy must not mask a renamed key) — matching the behavior on save. Omit when validating a brand-new rule.
"550e8400-e29b-41d4-a716-446655440002"
Response
Validation result
Human-readable validation result or error detail
"CEL condition is valid"
Additional context about validation scope (present only on success)
"Validation checks syntax only. Field references are not verified against an event schema."
Whether the condition is syntactically valid
true
Non-blocking advisories — e.g. a counter/tag/attribute key referenced in a condition/action expression that no rule in the program writes (likely a typo), or a deprecated CEL alias. Never affects validity.
Show child attributes
Show child attributes