curl --request POST \
--url https://api.scrip.dev/v1/rules \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data @- <<EOF
{
"actions": [
{
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Purchase reward",
"expires_at": "365d",
"matures_at": "30d",
"type": "CREDIT"
}
],
"condition": "event.type == 'purchase'",
"name": "Purchase Reward",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"active_from": "2024-01-01T00:00:00Z",
"active_to": "2024-12-31T23:59:59Z",
"budgets": [
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"limit": "10000.00",
"scope": "PROGRAM"
}
],
"description": "Awards 10 points per dollar spent",
"position": {
"placement": "before",
"reference_id": "550e8400-e29b-41d4-a716-446655440000"
},
"rule_set_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "ACTIVE",
"stop_after_match": false
}
EOFimport requests
url = "https://api.scrip.dev/v1/rules"
payload = {
"actions": [
{
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Purchase reward",
"expires_at": "365d",
"matures_at": "30d",
"type": "CREDIT"
}
],
"condition": "event.type == 'purchase'",
"name": "Purchase Reward",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"active_from": "2024-01-01T00:00:00Z",
"active_to": "2024-12-31T23:59:59Z",
"budgets": [
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"limit": "10000.00",
"scope": "PROGRAM"
}
],
"description": "Awards 10 points per dollar spent",
"position": {
"placement": "before",
"reference_id": "550e8400-e29b-41d4-a716-446655440000"
},
"rule_set_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "ACTIVE",
"stop_after_match": False
}
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({
actions: [
{
amount: '${{ event.amount * 0.03 }}',
asset_id: '550e8400-e29b-41d4-a716-446655440000',
description: 'Purchase reward',
expires_at: '365d',
matures_at: '30d',
type: 'CREDIT'
}
],
condition: 'event.type == \'purchase\'',
name: 'Purchase Reward',
program_id: '550e8400-e29b-41d4-a716-446655440000',
active_from: '2024-01-01T00:00:00Z',
active_to: '2024-12-31T23:59:59Z',
budgets: [
{
asset_id: '550e8400-e29b-41d4-a716-446655440000',
limit: '10000.00',
scope: 'PROGRAM'
}
],
description: 'Awards 10 points per dollar spent',
position: {placement: 'before', reference_id: '550e8400-e29b-41d4-a716-446655440000'},
rule_set_id: '550e8400-e29b-41d4-a716-446655440001',
status: 'ACTIVE',
stop_after_match: false
})
};
fetch('https://api.scrip.dev/v1/rules', 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",
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([
'actions' => [
[
'amount' => '${{ event.amount * 0.03 }}',
'asset_id' => '550e8400-e29b-41d4-a716-446655440000',
'description' => 'Purchase reward',
'expires_at' => '365d',
'matures_at' => '30d',
'type' => 'CREDIT'
]
],
'condition' => 'event.type == \'purchase\'',
'name' => 'Purchase Reward',
'program_id' => '550e8400-e29b-41d4-a716-446655440000',
'active_from' => '2024-01-01T00:00:00Z',
'active_to' => '2024-12-31T23:59:59Z',
'budgets' => [
[
'asset_id' => '550e8400-e29b-41d4-a716-446655440000',
'limit' => '10000.00',
'scope' => 'PROGRAM'
]
],
'description' => 'Awards 10 points per dollar spent',
'position' => [
'placement' => 'before',
'reference_id' => '550e8400-e29b-41d4-a716-446655440000'
],
'rule_set_id' => '550e8400-e29b-41d4-a716-446655440001',
'status' => 'ACTIVE',
'stop_after_match' => false
]),
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"
payload := strings.NewReader("{\n \"actions\": [\n {\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"description\": \"Purchase reward\",\n \"expires_at\": \"365d\",\n \"matures_at\": \"30d\",\n \"type\": \"CREDIT\"\n }\n ],\n \"condition\": \"event.type == 'purchase'\",\n \"name\": \"Purchase Reward\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"active_from\": \"2024-01-01T00:00:00Z\",\n \"active_to\": \"2024-12-31T23:59:59Z\",\n \"budgets\": [\n {\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"limit\": \"10000.00\",\n \"scope\": \"PROGRAM\"\n }\n ],\n \"description\": \"Awards 10 points per dollar spent\",\n \"position\": {\n \"placement\": \"before\",\n \"reference_id\": \"550e8400-e29b-41d4-a716-446655440000\"\n },\n \"rule_set_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"status\": \"ACTIVE\",\n \"stop_after_match\": false\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")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"actions\": [\n {\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"description\": \"Purchase reward\",\n \"expires_at\": \"365d\",\n \"matures_at\": \"30d\",\n \"type\": \"CREDIT\"\n }\n ],\n \"condition\": \"event.type == 'purchase'\",\n \"name\": \"Purchase Reward\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"active_from\": \"2024-01-01T00:00:00Z\",\n \"active_to\": \"2024-12-31T23:59:59Z\",\n \"budgets\": [\n {\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"limit\": \"10000.00\",\n \"scope\": \"PROGRAM\"\n }\n ],\n \"description\": \"Awards 10 points per dollar spent\",\n \"position\": {\n \"placement\": \"before\",\n \"reference_id\": \"550e8400-e29b-41d4-a716-446655440000\"\n },\n \"rule_set_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"status\": \"ACTIVE\",\n \"stop_after_match\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/rules")
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 \"actions\": [\n {\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"description\": \"Purchase reward\",\n \"expires_at\": \"365d\",\n \"matures_at\": \"30d\",\n \"type\": \"CREDIT\"\n }\n ],\n \"condition\": \"event.type == 'purchase'\",\n \"name\": \"Purchase Reward\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"active_from\": \"2024-01-01T00:00:00Z\",\n \"active_to\": \"2024-12-31T23:59:59Z\",\n \"budgets\": [\n {\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"limit\": \"10000.00\",\n \"scope\": \"PROGRAM\"\n }\n ],\n \"description\": \"Awards 10 points per dollar spent\",\n \"position\": {\n \"placement\": \"before\",\n \"reference_id\": \"550e8400-e29b-41d4-a716-446655440000\"\n },\n \"rule_set_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"status\": \"ACTIVE\",\n \"stop_after_match\": false\n}"
response = http.request(request)
puts response.read_body{
"actions": [
{
"amount": "${{ event.amount * 10 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440002",
"type": "CREDIT"
}
],
"active_from": "2024-01-01T00:00:00Z",
"active_to": "2024-12-31T23:59:59Z",
"budgets": [
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"consumed": "4500.00",
"cron_expression": "0 0 1 * *",
"interval": "720h",
"limit": "10000.00",
"next_reset_at": "2026-03-01T00:00:00Z",
"schedule_type": "CRON",
"scope": "PROGRAM"
}
],
"condition": "event.type == 'purchase' && event.amount > 0",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": "2024-06-01T00:00:00Z",
"description": "Awards 10 points per dollar spent",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Purchase Reward",
"order": 1,
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"rule_configuration_version": 4,
"rule_set_id": "550e8400-e29b-41d4-a716-446655440002",
"status": "ACTIVE",
"stop_after_match": false,
"updated_at": "2024-01-15T10:30:00Z",
"warnings": [
{
"client_ref": "<string>",
"code": "unknown_state_key",
"key": "purchaseCnt",
"kind": "counter",
"message": "unknown counter \"purchaseCnt\" — no rule in this program writes it; did you mean \"purchase_count\"?",
"rule_id": "<string>",
"rule_set_id": "<string>",
"scope": "participant",
"suggestion": "purchase_count"
}
]
}{
"code": "bad_request",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Missing or invalid credentials"
}{
"code": "forbidden",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Insufficient permissions for this action"
}{
"code": "not_found",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Resource not found"
}{
"code": "conflict",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Resource already exists or state conflict"
}{
"code": "unsupported_media_type",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Content-Type must be application/json"
}{
"code": "unprocessable",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Business rule violation"
}{
"code": "internal_error",
"message": "An internal error occurred"
}Create a rule
Create a rule that evaluates a CEL condition against incoming events and executes actions when matched. Omit rule_set_id to use the default set. Omit position to append, or use first/last/before/after placement. ACTIVE and SUSPENDED rules retain unique positions 1..N. The response includes the resulting rule_configuration_version.
curl --request POST \
--url https://api.scrip.dev/v1/rules \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data @- <<EOF
{
"actions": [
{
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Purchase reward",
"expires_at": "365d",
"matures_at": "30d",
"type": "CREDIT"
}
],
"condition": "event.type == 'purchase'",
"name": "Purchase Reward",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"active_from": "2024-01-01T00:00:00Z",
"active_to": "2024-12-31T23:59:59Z",
"budgets": [
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"limit": "10000.00",
"scope": "PROGRAM"
}
],
"description": "Awards 10 points per dollar spent",
"position": {
"placement": "before",
"reference_id": "550e8400-e29b-41d4-a716-446655440000"
},
"rule_set_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "ACTIVE",
"stop_after_match": false
}
EOFimport requests
url = "https://api.scrip.dev/v1/rules"
payload = {
"actions": [
{
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Purchase reward",
"expires_at": "365d",
"matures_at": "30d",
"type": "CREDIT"
}
],
"condition": "event.type == 'purchase'",
"name": "Purchase Reward",
"program_id": "550e8400-e29b-41d4-a716-446655440000",
"active_from": "2024-01-01T00:00:00Z",
"active_to": "2024-12-31T23:59:59Z",
"budgets": [
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"limit": "10000.00",
"scope": "PROGRAM"
}
],
"description": "Awards 10 points per dollar spent",
"position": {
"placement": "before",
"reference_id": "550e8400-e29b-41d4-a716-446655440000"
},
"rule_set_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "ACTIVE",
"stop_after_match": False
}
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({
actions: [
{
amount: '${{ event.amount * 0.03 }}',
asset_id: '550e8400-e29b-41d4-a716-446655440000',
description: 'Purchase reward',
expires_at: '365d',
matures_at: '30d',
type: 'CREDIT'
}
],
condition: 'event.type == \'purchase\'',
name: 'Purchase Reward',
program_id: '550e8400-e29b-41d4-a716-446655440000',
active_from: '2024-01-01T00:00:00Z',
active_to: '2024-12-31T23:59:59Z',
budgets: [
{
asset_id: '550e8400-e29b-41d4-a716-446655440000',
limit: '10000.00',
scope: 'PROGRAM'
}
],
description: 'Awards 10 points per dollar spent',
position: {placement: 'before', reference_id: '550e8400-e29b-41d4-a716-446655440000'},
rule_set_id: '550e8400-e29b-41d4-a716-446655440001',
status: 'ACTIVE',
stop_after_match: false
})
};
fetch('https://api.scrip.dev/v1/rules', 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",
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([
'actions' => [
[
'amount' => '${{ event.amount * 0.03 }}',
'asset_id' => '550e8400-e29b-41d4-a716-446655440000',
'description' => 'Purchase reward',
'expires_at' => '365d',
'matures_at' => '30d',
'type' => 'CREDIT'
]
],
'condition' => 'event.type == \'purchase\'',
'name' => 'Purchase Reward',
'program_id' => '550e8400-e29b-41d4-a716-446655440000',
'active_from' => '2024-01-01T00:00:00Z',
'active_to' => '2024-12-31T23:59:59Z',
'budgets' => [
[
'asset_id' => '550e8400-e29b-41d4-a716-446655440000',
'limit' => '10000.00',
'scope' => 'PROGRAM'
]
],
'description' => 'Awards 10 points per dollar spent',
'position' => [
'placement' => 'before',
'reference_id' => '550e8400-e29b-41d4-a716-446655440000'
],
'rule_set_id' => '550e8400-e29b-41d4-a716-446655440001',
'status' => 'ACTIVE',
'stop_after_match' => false
]),
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"
payload := strings.NewReader("{\n \"actions\": [\n {\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"description\": \"Purchase reward\",\n \"expires_at\": \"365d\",\n \"matures_at\": \"30d\",\n \"type\": \"CREDIT\"\n }\n ],\n \"condition\": \"event.type == 'purchase'\",\n \"name\": \"Purchase Reward\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"active_from\": \"2024-01-01T00:00:00Z\",\n \"active_to\": \"2024-12-31T23:59:59Z\",\n \"budgets\": [\n {\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"limit\": \"10000.00\",\n \"scope\": \"PROGRAM\"\n }\n ],\n \"description\": \"Awards 10 points per dollar spent\",\n \"position\": {\n \"placement\": \"before\",\n \"reference_id\": \"550e8400-e29b-41d4-a716-446655440000\"\n },\n \"rule_set_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"status\": \"ACTIVE\",\n \"stop_after_match\": false\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")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"actions\": [\n {\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"description\": \"Purchase reward\",\n \"expires_at\": \"365d\",\n \"matures_at\": \"30d\",\n \"type\": \"CREDIT\"\n }\n ],\n \"condition\": \"event.type == 'purchase'\",\n \"name\": \"Purchase Reward\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"active_from\": \"2024-01-01T00:00:00Z\",\n \"active_to\": \"2024-12-31T23:59:59Z\",\n \"budgets\": [\n {\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"limit\": \"10000.00\",\n \"scope\": \"PROGRAM\"\n }\n ],\n \"description\": \"Awards 10 points per dollar spent\",\n \"position\": {\n \"placement\": \"before\",\n \"reference_id\": \"550e8400-e29b-41d4-a716-446655440000\"\n },\n \"rule_set_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"status\": \"ACTIVE\",\n \"stop_after_match\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/rules")
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 \"actions\": [\n {\n \"amount\": \"${{ event.amount * 0.03 }}\",\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"description\": \"Purchase reward\",\n \"expires_at\": \"365d\",\n \"matures_at\": \"30d\",\n \"type\": \"CREDIT\"\n }\n ],\n \"condition\": \"event.type == 'purchase'\",\n \"name\": \"Purchase Reward\",\n \"program_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"active_from\": \"2024-01-01T00:00:00Z\",\n \"active_to\": \"2024-12-31T23:59:59Z\",\n \"budgets\": [\n {\n \"asset_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"limit\": \"10000.00\",\n \"scope\": \"PROGRAM\"\n }\n ],\n \"description\": \"Awards 10 points per dollar spent\",\n \"position\": {\n \"placement\": \"before\",\n \"reference_id\": \"550e8400-e29b-41d4-a716-446655440000\"\n },\n \"rule_set_id\": \"550e8400-e29b-41d4-a716-446655440001\",\n \"status\": \"ACTIVE\",\n \"stop_after_match\": false\n}"
response = http.request(request)
puts response.read_body{
"actions": [
{
"amount": "${{ event.amount * 10 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440002",
"type": "CREDIT"
}
],
"active_from": "2024-01-01T00:00:00Z",
"active_to": "2024-12-31T23:59:59Z",
"budgets": [
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"consumed": "4500.00",
"cron_expression": "0 0 1 * *",
"interval": "720h",
"limit": "10000.00",
"next_reset_at": "2026-03-01T00:00:00Z",
"schedule_type": "CRON",
"scope": "PROGRAM"
}
],
"condition": "event.type == 'purchase' && event.amount > 0",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": "2024-06-01T00:00:00Z",
"description": "Awards 10 points per dollar spent",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Purchase Reward",
"order": 1,
"program_id": "550e8400-e29b-41d4-a716-446655440001",
"rule_configuration_version": 4,
"rule_set_id": "550e8400-e29b-41d4-a716-446655440002",
"status": "ACTIVE",
"stop_after_match": false,
"updated_at": "2024-01-15T10:30:00Z",
"warnings": [
{
"client_ref": "<string>",
"code": "unknown_state_key",
"key": "purchaseCnt",
"kind": "counter",
"message": "unknown counter \"purchaseCnt\" — no rule in this program writes it; did you mean \"purchase_count\"?",
"rule_id": "<string>",
"rule_set_id": "<string>",
"scope": "participant",
"suggestion": "purchase_count"
}
]
}{
"code": "bad_request",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Missing or invalid credentials"
}{
"code": "forbidden",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Insufficient permissions for this action"
}{
"code": "not_found",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Resource not found"
}{
"code": "conflict",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Resource already exists or state conflict"
}{
"code": "unsupported_media_type",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Content-Type must be application/json"
}{
"code": "unprocessable",
"details": {
"expected": "<string>",
"field": "<string>",
"fields": [
{
"expected": "<unknown>",
"field": "<string>",
"message": "This field is required",
"reason": "required",
"received": "<string>"
}
],
"reason": "invalid",
"received": "<string>"
},
"message": "Business rule violation"
}{
"code": "internal_error",
"message": "An internal error occurred"
}condition that is evaluated against each incoming event and an actions array that executes when the condition matches. Use description to add a human-readable summary of what the rule does. Common actions include crediting balances, incrementing counters, and setting tags.
Pass rule_set_id to choose a containing set. Omit it to use the program’s default set. To place the rule, use position with first, last, before, or after. Relative placement requires the stable sibling ID in reference_id. If you omit position, Scrip appends the rule.
Scrip numbers rule positions 1..N with no gaps within each set. ACTIVE and SUSPENDED rules both occupy unique positions.
Set stop_after_match to true to prevent later rules in the same set from firing after this rule matches and its actions execute successfully. Other rule sets continue. A skipped execution, such as BUDGET_EXCEEDED, does not trigger the stop.
active_from and active_to define an optional time window using RFC 3339 timestamps. The window is checked against the event’s event_timestamp (the same value CEL sees as now), not the wall-clock time at processing. active_from is inclusive, active_to is exclusive. A matching rule outside the window records an OUTSIDE_TIME_WINDOW skipped evaluation. Event timestamps are caller-supplied, so historical imports with an event_timestamp inside a past window do fire time-windowed rules. Use these to layer promotional rules on top of permanent base rules.
budgets limit how much of an asset the rule can credit. Use PROGRAM for a shared limit or PARTICIPANT for a limit per recipient. You can set one of each for the same asset. A credit that would exceed either limit skips the whole rule. See Budgets for schedules, validation errors, skip reasons, and resets.
A rule is created in ACTIVE status by default. You can also set it to SUSPENDED at creation. Rules cannot be created under an archived program. The response includes the resulting rule_configuration_version.
Authorizations
API key passed in the X-API-Key header.
Body
Rule with CEL condition and actions array
Request body for creating a new rule with CEL condition and actions
Actions to execute when the condition matches (must be non-empty). Each action has a type field that determines which other fields are relevant.
1Credit an asset to the target. Requires asset_id and a positive amount. reference_id, expires_at, and matures_at require a LOT-mode asset and are rejected on a SIMPLE-mode asset.
- CREDIT action
- DEBIT action
- HOLD action
- RELEASE action
- RELEASE action
- FORFEIT action
- VOID_HOLD action
- TAG action
- UNTAG action
- COUNTER action
- SET_ATTRIBUTE action
- SET_TIER action
- SCHEDULE_EVENT action
- BROADCAST action
Show child attributes
Show child attributes
{
"amount": "${{ event.amount * 0.03 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Purchase reward",
"expires_at": "365d",
"matures_at": "30d",
"type": "CREDIT"
}
CEL expression that determines when the rule fires
1"event.type == 'purchase'"
Display name for the rule
1 - 255"Purchase Reward"
Program to attach this rule to
"550e8400-e29b-41d4-a716-446655440000"
Start of the rule's active window (RFC 3339). Null means immediately active. Checked against the event's event_timestamp, inclusive.
"2024-01-01T00:00:00Z"
End of the rule's active window (RFC 3339). Null means no end date. Checked against the event's event_timestamp, exclusive.
"2024-12-31T23:59:59Z"
Optional budget constraints for this rule. Omit or pass null for no budgets.
Never resets. schedule_type, cron_expression, and interval are all rejected.
- Lifetime budget
- Cron budget
- Interval budget
Show child attributes
Show child attributes
Human-readable summary of what this rule does
1000"Awards 10 points per dollar spent"
Semantic insertion. Omit both order and position to append.
- Option 1
- Option 2
Show child attributes
Show child attributes
Rule set to attach this rule to. Omit to use the program's default set.
"550e8400-e29b-41d4-a716-446655440001"
Initial lifecycle status (ACTIVE or SUSPENDED). Defaults to ACTIVE.
ACTIVE, SUSPENDED "ACTIVE"
When true, no subsequent rules in this set evaluate after this one matches; other sets continue
false
Response
Rule created
Actions to execute when the condition matches
[
{
"amount": "${{ event.amount * 10 }}",
"asset_id": "550e8400-e29b-41d4-a716-446655440002",
"type": "CREDIT"
}
]
Start of the rule's active window (RFC 3339, null if always active). Checked against the event's event_timestamp, inclusive.
"2024-01-01T00:00:00Z"
End of the rule's active window (RFC 3339, null if no end date). Checked against the event's event_timestamp, exclusive.
"2024-12-31T23:59:59Z"
Budget constraints applied to this rule
Show child attributes
Show child attributes
CEL expression that determines when the rule fires
"event.type == 'purchase' && event.amount > 0"
When this rule was created (RFC 3339)
"2024-01-15T10:30:00Z"
When this rule was archived (null if not archived)
"2024-06-01T00:00:00Z"
Human-readable summary of what this rule does
"Awards 10 points per dollar spent"
Unique identifier for this rule
"550e8400-e29b-41d4-a716-446655440000"
Display name
"Purchase Reward"
Evaluation position within the containing rule set (lower = first; ACTIVE and SUSPENDED rules occupy unique positions)
1
Program this rule belongs to
"550e8400-e29b-41d4-a716-446655440001"
Resulting program rule-configuration revision. Present on mutation responses.
4
Rule set that contains this rule and scopes its order and stop_after_match behavior
"550e8400-e29b-41d4-a716-446655440002"
Lifecycle status: ACTIVE, SUSPENDED, or ARCHIVED
"ACTIVE"
When true, no subsequent rules in this set evaluate after this one matches; other sets continue
false
When this rule was last modified (RFC 3339)
"2024-01-15T10:30:00Z"
Non-blocking advisories about the rule's condition or action expressions, such as unknown state-key typos or deprecated CEL aliases. Present on create/update only; never blocks the save.
Show child attributes
Show child attributes