curl --request POST \
--url https://api.moonbounce.ai/v1/decisions/{decision_id}/previews \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"structure": {
"questions": {
"item_used": {
"type": "noul",
"instructions": "Has the customer used the item beyond trying it on or setting it up once?",
"reads": [
"state.message"
]
},
"defective": {
"type": "noul",
"instructions": "Does the customer describe a defect, damage on arrival, or the item failing under normal use?",
"reads": [
"state.message"
]
},
"shipping_failure": {
"type": "noul",
"instructions": "Did the order arrive later than promised, or get lost in transit?",
"reads": [
"state.message"
]
}
},
"attributes": {
"days_since_delivery": {
"type": "number",
"minimum": 0
}
},
"aggregations": {
"grant_score": {
"type": "weighted_mean",
"inputs": [
{
"name": "questions.item_used",
"invert": true
},
{
"name": "questions.defective"
},
{
"name": "questions.shipping_failure"
}
]
},
"handling": {
"type": "rules",
"rules": [
{
"when": {
"name": "attributes.days_since_delivery",
"gt": 30
},
"outcome": "escalate"
},
{
"when": {
"name": "aggregations.grant_score",
"gte": 0.72
},
"outcome": "grant"
},
{
"when": {
"name": "aggregations.grant_score",
"lt": 0.38
},
"outcome": "deny"
}
],
"else": "escalate"
}
},
"result": "aggregations.handling"
}
}
'import requests
url = "https://api.moonbounce.ai/v1/decisions/{decision_id}/previews"
payload = { "structure": {
"questions": {
"item_used": {
"type": "noul",
"instructions": "Has the customer used the item beyond trying it on or setting it up once?",
"reads": ["state.message"]
},
"defective": {
"type": "noul",
"instructions": "Does the customer describe a defect, damage on arrival, or the item failing under normal use?",
"reads": ["state.message"]
},
"shipping_failure": {
"type": "noul",
"instructions": "Did the order arrive later than promised, or get lost in transit?",
"reads": ["state.message"]
}
},
"attributes": { "days_since_delivery": {
"type": "number",
"minimum": 0
} },
"aggregations": {
"grant_score": {
"type": "weighted_mean",
"inputs": [{
"name": "questions.item_used",
"invert": True
}, { "name": "questions.defective" }, { "name": "questions.shipping_failure" }]
},
"handling": {
"type": "rules",
"rules": [
{
"when": {
"name": "attributes.days_since_delivery",
"gt": 30
},
"outcome": "escalate"
},
{
"when": {
"name": "aggregations.grant_score",
"gte": 0.72
},
"outcome": "grant"
},
{
"when": {
"name": "aggregations.grant_score",
"lt": 0.38
},
"outcome": "deny"
}
],
"else": "escalate"
}
},
"result": "aggregations.handling"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
structure: {
questions: {
item_used: {
type: 'noul',
instructions: 'Has the customer used the item beyond trying it on or setting it up once?',
reads: ['state.message']
},
defective: {
type: 'noul',
instructions: 'Does the customer describe a defect, damage on arrival, or the item failing under normal use?',
reads: ['state.message']
},
shipping_failure: {
type: 'noul',
instructions: 'Did the order arrive later than promised, or get lost in transit?',
reads: ['state.message']
}
},
attributes: {days_since_delivery: {type: 'number', minimum: 0}},
aggregations: {
grant_score: {
type: 'weighted_mean',
inputs: [
{name: 'questions.item_used', invert: true},
{name: 'questions.defective'},
{name: 'questions.shipping_failure'}
]
},
handling: {
type: 'rules',
rules: [
{when: {name: 'attributes.days_since_delivery', gt: 30}, outcome: 'escalate'},
{when: {name: 'aggregations.grant_score', gte: 0.72}, outcome: 'grant'},
{when: {name: 'aggregations.grant_score', lt: 0.38}, outcome: 'deny'}
],
else: 'escalate'
}
},
result: 'aggregations.handling'
}
})
};
fetch('https://api.moonbounce.ai/v1/decisions/{decision_id}/previews', 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.moonbounce.ai/v1/decisions/{decision_id}/previews",
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([
'structure' => [
'questions' => [
'item_used' => [
'type' => 'noul',
'instructions' => 'Has the customer used the item beyond trying it on or setting it up once?',
'reads' => [
'state.message'
]
],
'defective' => [
'type' => 'noul',
'instructions' => 'Does the customer describe a defect, damage on arrival, or the item failing under normal use?',
'reads' => [
'state.message'
]
],
'shipping_failure' => [
'type' => 'noul',
'instructions' => 'Did the order arrive later than promised, or get lost in transit?',
'reads' => [
'state.message'
]
]
],
'attributes' => [
'days_since_delivery' => [
'type' => 'number',
'minimum' => 0
]
],
'aggregations' => [
'grant_score' => [
'type' => 'weighted_mean',
'inputs' => [
[
'name' => 'questions.item_used',
'invert' => true
],
[
'name' => 'questions.defective'
],
[
'name' => 'questions.shipping_failure'
]
]
],
'handling' => [
'type' => 'rules',
'rules' => [
[
'when' => [
'name' => 'attributes.days_since_delivery',
'gt' => 30
],
'outcome' => 'escalate'
],
[
'when' => [
'name' => 'aggregations.grant_score',
'gte' => 0.72
],
'outcome' => 'grant'
],
[
'when' => [
'name' => 'aggregations.grant_score',
'lt' => 0.38
],
'outcome' => 'deny'
]
],
'else' => 'escalate'
]
],
'result' => 'aggregations.handling'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.moonbounce.ai/v1/decisions/{decision_id}/previews"
payload := strings.NewReader("{\n \"structure\": {\n \"questions\": {\n \"item_used\": {\n \"type\": \"noul\",\n \"instructions\": \"Has the customer used the item beyond trying it on or setting it up once?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"defective\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer describe a defect, damage on arrival, or the item failing under normal use?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"shipping_failure\": {\n \"type\": \"noul\",\n \"instructions\": \"Did the order arrive later than promised, or get lost in transit?\",\n \"reads\": [\n \"state.message\"\n ]\n }\n },\n \"attributes\": {\n \"days_since_delivery\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"aggregations\": {\n \"grant_score\": {\n \"type\": \"weighted_mean\",\n \"inputs\": [\n {\n \"name\": \"questions.item_used\",\n \"invert\": true\n },\n {\n \"name\": \"questions.defective\"\n },\n {\n \"name\": \"questions.shipping_failure\"\n }\n ]\n },\n \"handling\": {\n \"type\": \"rules\",\n \"rules\": [\n {\n \"when\": {\n \"name\": \"attributes.days_since_delivery\",\n \"gt\": 30\n },\n \"outcome\": \"escalate\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"gte\": 0.72\n },\n \"outcome\": \"grant\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"lt\": 0.38\n },\n \"outcome\": \"deny\"\n }\n ],\n \"else\": \"escalate\"\n }\n },\n \"result\": \"aggregations.handling\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
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.moonbounce.ai/v1/decisions/{decision_id}/previews")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"structure\": {\n \"questions\": {\n \"item_used\": {\n \"type\": \"noul\",\n \"instructions\": \"Has the customer used the item beyond trying it on or setting it up once?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"defective\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer describe a defect, damage on arrival, or the item failing under normal use?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"shipping_failure\": {\n \"type\": \"noul\",\n \"instructions\": \"Did the order arrive later than promised, or get lost in transit?\",\n \"reads\": [\n \"state.message\"\n ]\n }\n },\n \"attributes\": {\n \"days_since_delivery\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"aggregations\": {\n \"grant_score\": {\n \"type\": \"weighted_mean\",\n \"inputs\": [\n {\n \"name\": \"questions.item_used\",\n \"invert\": true\n },\n {\n \"name\": \"questions.defective\"\n },\n {\n \"name\": \"questions.shipping_failure\"\n }\n ]\n },\n \"handling\": {\n \"type\": \"rules\",\n \"rules\": [\n {\n \"when\": {\n \"name\": \"attributes.days_since_delivery\",\n \"gt\": 30\n },\n \"outcome\": \"escalate\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"gte\": 0.72\n },\n \"outcome\": \"grant\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"lt\": 0.38\n },\n \"outcome\": \"deny\"\n }\n ],\n \"else\": \"escalate\"\n }\n },\n \"result\": \"aggregations.handling\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonbounce.ai/v1/decisions/{decision_id}/previews")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"structure\": {\n \"questions\": {\n \"item_used\": {\n \"type\": \"noul\",\n \"instructions\": \"Has the customer used the item beyond trying it on or setting it up once?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"defective\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer describe a defect, damage on arrival, or the item failing under normal use?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"shipping_failure\": {\n \"type\": \"noul\",\n \"instructions\": \"Did the order arrive later than promised, or get lost in transit?\",\n \"reads\": [\n \"state.message\"\n ]\n }\n },\n \"attributes\": {\n \"days_since_delivery\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"aggregations\": {\n \"grant_score\": {\n \"type\": \"weighted_mean\",\n \"inputs\": [\n {\n \"name\": \"questions.item_used\",\n \"invert\": true\n },\n {\n \"name\": \"questions.defective\"\n },\n {\n \"name\": \"questions.shipping_failure\"\n }\n ]\n },\n \"handling\": {\n \"type\": \"rules\",\n \"rules\": [\n {\n \"when\": {\n \"name\": \"attributes.days_since_delivery\",\n \"gt\": 30\n },\n \"outcome\": \"escalate\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"gte\": 0.72\n },\n \"outcome\": \"grant\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"lt\": 0.38\n },\n \"outcome\": \"deny\"\n }\n ],\n \"else\": \"escalate\"\n }\n },\n \"result\": \"aggregations.handling\"\n }\n}"
response = http.request(request)
puts response.read_body{
"preview_id": "<string>",
"decision_id": "<string>",
"environment": "production",
"base": {
"structure_hash": "<string>",
"engine_profile": "<string>"
},
"candidate": {
"structure_hash": "<string>",
"engine_profile": "<string>"
},
"hashes_match": {
"structure": true
},
"evidence": {
"label": "starting_examples",
"frozen_at": "2023-11-07T05:31:56Z",
"by_split": {
"seed": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"train": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
}
},
"noise_rate": 0.5,
"action_mix": {
"before": {},
"after": {},
"on": "<string>",
"n": 1
},
"changed_items": [
{
"evaluation_id": "<string>",
"feedback_id": "<string>",
"split": "seed",
"change": "fix",
"before": {
"answers": {},
"outcome": "<string>",
"value": 123
},
"after": {
"answers": {},
"outcome": "<string>",
"value": 123
}
}
],
"credited_feedback": [
"<string>"
],
"by_source": {
"app_native": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"app_resolution": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"reviewer": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"owner": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"import": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"synthetic_review": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
}
}
},
"cost": {
"engine_calls": 1,
"cache_hits": 1,
"input_tokens": 1,
"usd_micros": 1
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}Preview a structure change against past feedback
Replays a structure change over past cases with feedback: it spends engine calls and stores a run. Not a dry run of evaluate. Replays a local structure and its base over the decision’s reviewed and seeded cases in the key’s environment (a test key previews against test cases only), and returns fixes, breaks, the action mix and an evidence label: training_cases when a scored case is a training case (its group’s first feedback was not an import), else starting_examples (every scored case is an imported example); either way the cases are ones a suggestion may have learned from. The result must decide outcomes (bands, rules or match): a value result is 400 OUTCOMES_INVALID. Each case reuses the answers its evaluation stored for questions whose hash is unchanged; changed and new questions are asked the way evaluate asks them (each question’s reads, grouped into System One calls), so a preview costs what evaluating the changed questions would. Writes an eval run only: never an evaluation, never traffic, never acceptance. A preview does not register the candidate: before evaluating by its structure hash, register it with POST /v1/decisions//structures (or send the structure inline on evaluate once). The base, in order: the base of suggestion_id when it is sent (then base is ignored), else base, else the version serving primary traffic in the key’s environment, else the newest one seeded there, else none. With suggestion_id, hashes_match says whether the structure is that suggestion’s candidate; another environment’s suggestion is 404. The evidence replays only cases with an outcome from the owner, reviewers or seeds; the action mix replays a sample of the environment’s recent primary traffic. For questions the candidate changes, before is a fresh re-run of the base question (the fair baseline), so engine nondeterminism can move it between previews. noise_rate measures outcome flips from that re-run against the stored answers, not value drift. A test key’s preview neither reads nor fills the shared cache of engine answers. A decision nothing was registered, evaluated or seeded under is 404.
curl --request POST \
--url https://api.moonbounce.ai/v1/decisions/{decision_id}/previews \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"structure": {
"questions": {
"item_used": {
"type": "noul",
"instructions": "Has the customer used the item beyond trying it on or setting it up once?",
"reads": [
"state.message"
]
},
"defective": {
"type": "noul",
"instructions": "Does the customer describe a defect, damage on arrival, or the item failing under normal use?",
"reads": [
"state.message"
]
},
"shipping_failure": {
"type": "noul",
"instructions": "Did the order arrive later than promised, or get lost in transit?",
"reads": [
"state.message"
]
}
},
"attributes": {
"days_since_delivery": {
"type": "number",
"minimum": 0
}
},
"aggregations": {
"grant_score": {
"type": "weighted_mean",
"inputs": [
{
"name": "questions.item_used",
"invert": true
},
{
"name": "questions.defective"
},
{
"name": "questions.shipping_failure"
}
]
},
"handling": {
"type": "rules",
"rules": [
{
"when": {
"name": "attributes.days_since_delivery",
"gt": 30
},
"outcome": "escalate"
},
{
"when": {
"name": "aggregations.grant_score",
"gte": 0.72
},
"outcome": "grant"
},
{
"when": {
"name": "aggregations.grant_score",
"lt": 0.38
},
"outcome": "deny"
}
],
"else": "escalate"
}
},
"result": "aggregations.handling"
}
}
'import requests
url = "https://api.moonbounce.ai/v1/decisions/{decision_id}/previews"
payload = { "structure": {
"questions": {
"item_used": {
"type": "noul",
"instructions": "Has the customer used the item beyond trying it on or setting it up once?",
"reads": ["state.message"]
},
"defective": {
"type": "noul",
"instructions": "Does the customer describe a defect, damage on arrival, or the item failing under normal use?",
"reads": ["state.message"]
},
"shipping_failure": {
"type": "noul",
"instructions": "Did the order arrive later than promised, or get lost in transit?",
"reads": ["state.message"]
}
},
"attributes": { "days_since_delivery": {
"type": "number",
"minimum": 0
} },
"aggregations": {
"grant_score": {
"type": "weighted_mean",
"inputs": [{
"name": "questions.item_used",
"invert": True
}, { "name": "questions.defective" }, { "name": "questions.shipping_failure" }]
},
"handling": {
"type": "rules",
"rules": [
{
"when": {
"name": "attributes.days_since_delivery",
"gt": 30
},
"outcome": "escalate"
},
{
"when": {
"name": "aggregations.grant_score",
"gte": 0.72
},
"outcome": "grant"
},
{
"when": {
"name": "aggregations.grant_score",
"lt": 0.38
},
"outcome": "deny"
}
],
"else": "escalate"
}
},
"result": "aggregations.handling"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
structure: {
questions: {
item_used: {
type: 'noul',
instructions: 'Has the customer used the item beyond trying it on or setting it up once?',
reads: ['state.message']
},
defective: {
type: 'noul',
instructions: 'Does the customer describe a defect, damage on arrival, or the item failing under normal use?',
reads: ['state.message']
},
shipping_failure: {
type: 'noul',
instructions: 'Did the order arrive later than promised, or get lost in transit?',
reads: ['state.message']
}
},
attributes: {days_since_delivery: {type: 'number', minimum: 0}},
aggregations: {
grant_score: {
type: 'weighted_mean',
inputs: [
{name: 'questions.item_used', invert: true},
{name: 'questions.defective'},
{name: 'questions.shipping_failure'}
]
},
handling: {
type: 'rules',
rules: [
{when: {name: 'attributes.days_since_delivery', gt: 30}, outcome: 'escalate'},
{when: {name: 'aggregations.grant_score', gte: 0.72}, outcome: 'grant'},
{when: {name: 'aggregations.grant_score', lt: 0.38}, outcome: 'deny'}
],
else: 'escalate'
}
},
result: 'aggregations.handling'
}
})
};
fetch('https://api.moonbounce.ai/v1/decisions/{decision_id}/previews', 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.moonbounce.ai/v1/decisions/{decision_id}/previews",
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([
'structure' => [
'questions' => [
'item_used' => [
'type' => 'noul',
'instructions' => 'Has the customer used the item beyond trying it on or setting it up once?',
'reads' => [
'state.message'
]
],
'defective' => [
'type' => 'noul',
'instructions' => 'Does the customer describe a defect, damage on arrival, or the item failing under normal use?',
'reads' => [
'state.message'
]
],
'shipping_failure' => [
'type' => 'noul',
'instructions' => 'Did the order arrive later than promised, or get lost in transit?',
'reads' => [
'state.message'
]
]
],
'attributes' => [
'days_since_delivery' => [
'type' => 'number',
'minimum' => 0
]
],
'aggregations' => [
'grant_score' => [
'type' => 'weighted_mean',
'inputs' => [
[
'name' => 'questions.item_used',
'invert' => true
],
[
'name' => 'questions.defective'
],
[
'name' => 'questions.shipping_failure'
]
]
],
'handling' => [
'type' => 'rules',
'rules' => [
[
'when' => [
'name' => 'attributes.days_since_delivery',
'gt' => 30
],
'outcome' => 'escalate'
],
[
'when' => [
'name' => 'aggregations.grant_score',
'gte' => 0.72
],
'outcome' => 'grant'
],
[
'when' => [
'name' => 'aggregations.grant_score',
'lt' => 0.38
],
'outcome' => 'deny'
]
],
'else' => 'escalate'
]
],
'result' => 'aggregations.handling'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.moonbounce.ai/v1/decisions/{decision_id}/previews"
payload := strings.NewReader("{\n \"structure\": {\n \"questions\": {\n \"item_used\": {\n \"type\": \"noul\",\n \"instructions\": \"Has the customer used the item beyond trying it on or setting it up once?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"defective\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer describe a defect, damage on arrival, or the item failing under normal use?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"shipping_failure\": {\n \"type\": \"noul\",\n \"instructions\": \"Did the order arrive later than promised, or get lost in transit?\",\n \"reads\": [\n \"state.message\"\n ]\n }\n },\n \"attributes\": {\n \"days_since_delivery\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"aggregations\": {\n \"grant_score\": {\n \"type\": \"weighted_mean\",\n \"inputs\": [\n {\n \"name\": \"questions.item_used\",\n \"invert\": true\n },\n {\n \"name\": \"questions.defective\"\n },\n {\n \"name\": \"questions.shipping_failure\"\n }\n ]\n },\n \"handling\": {\n \"type\": \"rules\",\n \"rules\": [\n {\n \"when\": {\n \"name\": \"attributes.days_since_delivery\",\n \"gt\": 30\n },\n \"outcome\": \"escalate\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"gte\": 0.72\n },\n \"outcome\": \"grant\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"lt\": 0.38\n },\n \"outcome\": \"deny\"\n }\n ],\n \"else\": \"escalate\"\n }\n },\n \"result\": \"aggregations.handling\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
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.moonbounce.ai/v1/decisions/{decision_id}/previews")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"structure\": {\n \"questions\": {\n \"item_used\": {\n \"type\": \"noul\",\n \"instructions\": \"Has the customer used the item beyond trying it on or setting it up once?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"defective\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer describe a defect, damage on arrival, or the item failing under normal use?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"shipping_failure\": {\n \"type\": \"noul\",\n \"instructions\": \"Did the order arrive later than promised, or get lost in transit?\",\n \"reads\": [\n \"state.message\"\n ]\n }\n },\n \"attributes\": {\n \"days_since_delivery\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"aggregations\": {\n \"grant_score\": {\n \"type\": \"weighted_mean\",\n \"inputs\": [\n {\n \"name\": \"questions.item_used\",\n \"invert\": true\n },\n {\n \"name\": \"questions.defective\"\n },\n {\n \"name\": \"questions.shipping_failure\"\n }\n ]\n },\n \"handling\": {\n \"type\": \"rules\",\n \"rules\": [\n {\n \"when\": {\n \"name\": \"attributes.days_since_delivery\",\n \"gt\": 30\n },\n \"outcome\": \"escalate\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"gte\": 0.72\n },\n \"outcome\": \"grant\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"lt\": 0.38\n },\n \"outcome\": \"deny\"\n }\n ],\n \"else\": \"escalate\"\n }\n },\n \"result\": \"aggregations.handling\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moonbounce.ai/v1/decisions/{decision_id}/previews")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"structure\": {\n \"questions\": {\n \"item_used\": {\n \"type\": \"noul\",\n \"instructions\": \"Has the customer used the item beyond trying it on or setting it up once?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"defective\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer describe a defect, damage on arrival, or the item failing under normal use?\",\n \"reads\": [\n \"state.message\"\n ]\n },\n \"shipping_failure\": {\n \"type\": \"noul\",\n \"instructions\": \"Did the order arrive later than promised, or get lost in transit?\",\n \"reads\": [\n \"state.message\"\n ]\n }\n },\n \"attributes\": {\n \"days_since_delivery\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"aggregations\": {\n \"grant_score\": {\n \"type\": \"weighted_mean\",\n \"inputs\": [\n {\n \"name\": \"questions.item_used\",\n \"invert\": true\n },\n {\n \"name\": \"questions.defective\"\n },\n {\n \"name\": \"questions.shipping_failure\"\n }\n ]\n },\n \"handling\": {\n \"type\": \"rules\",\n \"rules\": [\n {\n \"when\": {\n \"name\": \"attributes.days_since_delivery\",\n \"gt\": 30\n },\n \"outcome\": \"escalate\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"gte\": 0.72\n },\n \"outcome\": \"grant\"\n },\n {\n \"when\": {\n \"name\": \"aggregations.grant_score\",\n \"lt\": 0.38\n },\n \"outcome\": \"deny\"\n }\n ],\n \"else\": \"escalate\"\n }\n },\n \"result\": \"aggregations.handling\"\n }\n}"
response = http.request(request)
puts response.read_body{
"preview_id": "<string>",
"decision_id": "<string>",
"environment": "production",
"base": {
"structure_hash": "<string>",
"engine_profile": "<string>"
},
"candidate": {
"structure_hash": "<string>",
"engine_profile": "<string>"
},
"hashes_match": {
"structure": true
},
"evidence": {
"label": "starting_examples",
"frozen_at": "2023-11-07T05:31:56Z",
"by_split": {
"seed": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"train": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
}
},
"noise_rate": 0.5,
"action_mix": {
"before": {},
"after": {},
"on": "<string>",
"n": 1
},
"changed_items": [
{
"evaluation_id": "<string>",
"feedback_id": "<string>",
"split": "seed",
"change": "fix",
"before": {
"answers": {},
"outcome": "<string>",
"value": 123
},
"after": {
"answers": {},
"outcome": "<string>",
"value": 123
}
}
],
"credited_feedback": [
"<string>"
],
"by_source": {
"app_native": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"app_resolution": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"reviewer": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"owner": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"import": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
},
"synthetic_review": {
"n": 1,
"fixes": 1,
"breaks": 1,
"base_correct": 1,
"candidate_correct": 1
}
}
},
"cost": {
"engine_calls": 1,
"cache_hits": 1,
"input_tokens": 1,
"usd_micros": 1
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"reason": "<string>",
"param": "<string>",
"details": {
"issues": [
{
"param": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}
}
}Authorizations
An API key, sent as Authorization: Bearer <key>. Each operation lists the scope its key needs: decisions:evaluate (evaluate and read evaluations), decisions:feedback (your app's feedback) or decisions:develop (everything else, including owner feedback and the review queue). An operation listing no scope takes any scoped key. A key with no scope, or without the operation's, gets 403 INSUFFICIENT_SCOPE.
Headers
Makes a retry safe. For 24 hours, the same key with the same request returns the first stored result (with Idempotent-Replayed: true); the same key with a different request is a 422 IDEMPOTENCY_KEY_REUSED. Keys are scoped to the organization and environment across every operation, so use a fresh key per request. A request that failed before its result was stored runs again when retried with its key.
1 - 255^[\x20-\x7e]+$Path Parameters
^[a-z][a-z0-9_.-]{0,127}$Body
Everything that defines a decision: questions, attribute declarations, aggregations and the result. Names are unique across all three maps.
Show child attributes
Show child attributes
^sug_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$Show child attributes
Show child attributes
Response
The preview
^run_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$^[a-z][a-z0-9_.-]{0,127}$The environment of the key that made the call: production or test. Evaluations, feedback, reviews and suggestions are separate per environment; registered structures are shared.
production, test Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes