DEVELOPER GUIDE
Build your first decision
A practical guide to this service: run, inspect, integrate, measure.
GPT-6 Luna Decisions from OpenAI is also available through OpenRouter with the shared Jev request and response format. This site is an independent workbench and API service for TypeSafe AI's Jev 1.13 and image-capable Jev 1.14, Liquid d1, Convai Innovations' Laya, Upstage's Solar Decide and Solar Decide Flash, Together AI's Tev1, Jared Palmer's Kev 4B, Perplexity's Decider V1 and V1.1, Inception's Mercury Decide, and Cloudflare's Clef Flash and Clef, Nace.AI's Drex v2.0, and Perplexity's Decider 27B Latest alias. Constrained answers can still be wrong; validate with your own data.
Quickstart
Create an account to receive 100 credits. Load a recipe, review its budget and run it. Tune the questions, save your configuration, and open the Code tab. Create a site API key to use the same credit balance from your server.
export DECISIONS_API_KEY="YOUR_API_KEY"
curl --fail-with-body 'https://decisions-api.dev/v1/systemone' \
-H "Authorization: Bearer $DECISIONS_API_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"model": "typesafe/jev-1.13",
"state": "I was charged twice for order A-4471. Please refund the duplicate payment.",
"questions": {
"route": {
"type": "choice",
"instructions": "Which team should handle this ticket? Use other when no option fits.",
"criteria": {
"billing": "Payments, charges and refunds",
"technical": "Bugs and product errors",
"account": "Login and account access",
"other": "None of these teams"
}
}
}
}'Keep API keys on your server. Do not embed them in browser code or commit them to source control.
API reference
POST https://decisions-api.dev/v1/systemone
Send JSON with model, state and questions. Use Authorization: Bearer with a key from this site. Successful responses use code: 0; answers live at data.result.answers. Official provider SDK response shapes differ. Text, JSON and image inputs are supported. Add up to 4 PNG, JPEG or WebP images (4 MiB each, 8 MiB total, 16 MP each); complete image requests may use 13 MiB, while text and questions stay within 32 KiB. The text-state cap does not include image bytes.
| Field | Shape |
|---|---|
| model | GPT-6 Luna Decisions from OpenAI is also available through OpenRouter with the shared Jev request and response format. Model ID: openai/gpt-6-luna-decisions. The playground and API support typesafe/jev-1.13 (alias: jev-latest), typesafe/jev-1.14, liquid/d1, convaiinnovations/laya, upstage/solar-decide, upstage/solar-decide-flash, togethercomputer/tev1-4b-experimental, jaredpalmer/kev-4b, perplexity/pplx-decider-v1-27b, perplexity/pplx-decider-v1.1-27b, ~perplexity/pplx-decider-27b-latest, inception/mercury-decide, cloudflare/clef-flash, cloudflare/clef, respan/span-01 and respan/span-01-lite. Liquid d1 and Laya use Vercel AI Gateway; the other models use OpenRouter. Span accepts Noul questions only; other models accept Choice, Score and Noul. Tev1 Choice accepts 2–20 options, Laya 2–100, Solar Decide Flash 2–26, and other general decision models 2–255. Solar Decide Flash and Mercury Decide are text-only. Jev 1.14, Perplexity Decider V1, V1.1 and Latest, GPT-6 Luna Decisions, Clef Flash and Clef accept images. The platform allows up to 8 questions and 32 KiB for text and questions. Image requests accept up to 4 PNG, JPEG or WebP images (4 MiB each, 8 MiB total, 16 MP each) and may use 13 MiB overall. Clef and Clef Flash text state is capped at 2,000 UTF-8 bytes. Also available: microsoft/microsoft-decision-1, nace-ai/drex-v1.5, nace-ai/drex-v2.0, cloudflare/clef-omni (text, JSON and images), inception/mercury-decide:free and respan/span-01-lite:free (Noul only). Clef Omni supports the general text limit; the 2,000-byte state cap applies only to Clef and Clef Flash. |
| state | Non-empty text, a JSON object or array. Shared by all questions. Span accepts text or {input: message array, output: assistant message}; every message has only role and text content. Generic JSON objects and bare arrays are not supported for Span. |
| images | Optional images: an array of up to 4 {url} objects. Jev 1.14, GPT-6 Luna Decisions, Perplexity Decider, Clef Omni, Clef Flash and Clef accept PNG, JPEG and WebP base64 data URLs or public HTTPS URLs from configured download hosts. Each embedded/downloaded image is limited to 4 MiB and 16 MP; images total 8 MiB, the complete request 13 MiB, and text plus questions 32 KiB. You may also send a state array containing text and image_url parts instead of images. Images are shared by all questions. Upstream receives embedded image parts; top-level images are converted by this service. |
| questions | 1–8 named questions. IDs start with a letter, followed by letters, digits, _ or -; maximum 64 characters. |
choice
Define 2–255 named options in criteria. The answer includes choice, probabilities and confidence. Add an explicit fallback option for cases that do not fit. Solar Decide Flash accepts at most 26 options.
score
Define 2–10 ordered strings in criteria. The score ranges from 0 to the last index and may be fractional; probabilities describe the levels.
noul
noul returns P(true), from 0 to 1. Optional criteria.true and criteria.false describe what counts as yes and no. It does not return a boolean; use your own threshold.
Probabilities are model outputs over your answer space. Confidence is a separate signal. Neither is a measured accuracy rate. For Noul, the threshold uses max(P(yes), 1 − P(yes)); 0.01 can be a decisive no. Validate thresholds against labeled cases in Compare rules.
Images
Optional images: an array of up to 4 {url} objects. Jev 1.14, GPT-6 Luna Decisions, Perplexity Decider, Clef Omni, Clef Flash and Clef accept PNG, JPEG and WebP base64 data URLs or public HTTPS URLs from configured download hosts. Each embedded/downloaded image is limited to 4 MiB and 16 MP; images total 8 MiB, the complete request 13 MiB, and text plus questions 32 KiB. You may also send a state array containing text and image_url parts instead of images. Images are shared by all questions. Upstream receives embedded image parts; top-level images are converted by this service.
// Server-side JavaScript (Node 20+ or Bun). Set DECISIONS_API_KEY.
import { readFileSync } from "node:fs";
// Place these local images beside this script, or edit their paths.
const payload = {
"model": "cloudflare/clef-flash",
"state": "Inspect the supplied screenshot.",
"questions": {
"screenshot": {
"type": "noul",
"instructions": "Does the image show a software interface?"
}
},
"images": [
{
"url": "READ_FROM_LOCAL_FILE"
}
]
};
payload.images[0].url = "data:image/png;base64," + readFileSync("image-1.png").toString("base64");
const response = await fetch("https://decisions-api.dev/v1/systemone", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.DECISIONS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
const body = await response.json();
if (!response.ok || body.code !== 0) throw new Error(body.message);
console.log(body.data.result.answers);
console.log(body.data.creditsUsed);Image code reads local files such as image-1.png. Save your images using the filenames in the code, or edit the paths. Image pixels are not stored during API setup.
The browser embeds downloaded images before running. API URL downloads allow only the app/storage hosts and DECISION_IMAGE_ALLOWED_HOSTS; redirects must also be allowed. Before a URL is downloaded, its budget preview reserves a full provider context per image and question; the server then reserves a smaller budget from its dimensions and charges actual input usage.
Illustrative response — not a live measurement
{
"code": 0,
"message": "ok",
"data": {
"requestId": "example-request-id",
"creditsUsed": 1,
"historySaved": true,
"result": {
"model": "typesafe/jev-1.13",
"answers": {
"route": {
"type": "choice",
"choice": "billing",
"probabilities": {
"billing": 0.94,
"technical": 0.02,
"account": 0.02,
"other": 0.02
},
"confidence": 0.9
}
},
"usage": {
"input_tokens": 1000,
"output_tokens": 0
},
"elapsedMs": 250
}
}
}Latency measures this service’s server processing time, including the provider round trip. It excludes the browser network trip and is not a performance guarantee.
Billing & limits
Input rates per million tokens: GPT-6 Luna Decisions 1,500 credits; Jev 1.14 and Perplexity Decider V1 600 each; Decider V1.1 and Mercury Decide 300 each; Clef Flash 600; Clef 3,500; Drex v2.0 900; Decider Latest 300 (current V1.1 route). Clef and Clef Flash cap JSON-serialized state at 2,000 UTF-8 bytes to reduce upstream text truncation. Up to 8 questions; text and questions fit within 32 KiB. Tev1 Choice accepts 2–20 options, Laya 2–100, Solar Decide Flash 2–26, and other general decision models 2–255. Web attempts are spaced at least 3 seconds apart. Web, API and evaluation charge actual input-token usage with the model's listed rate, rounded up and with a minimum of 1 credit per successful request; output is free. Before calling the provider, we reserve the displayed conservative budget. On success, we charge actual input tokens and return the remainder. Failed calls release the reservation; interrupted holds expire after 10 minutes and are released on the next balance check or request. Text, JSON and image inputs are supported. Add up to 4 PNG, JPEG or WebP images (4 MiB each, 8 MiB total, 16 MP each); complete image requests may use 13 MiB, while text and questions stay within 32 KiB. The text-state cap does not include image bytes. Microsoft-Decision-1, Drex v1.5 and Liquid d1 use 600 credits/M; Drex v2.0 uses 900 and Decider Latest uses 300 (based on its current V1.1 target). Clef Omni uses 2,200. Mercury Decide :free and Span-01 Lite :free cost 1 credit per successful request. Clef Omni accepts images and the general 32 KiB text limit.
400 invalid input · 401 sign-in/key required · 402 insufficient credits · 409 duplicate request · 413 request too large · 429 wait for Retry-After · 502 provider failure · 503 service unavailable. Send a unique Idempotency-Key (8–64 letters, digits, _ or -) per logical API request. Reusing it returns 409 without another model call. Check history before retrying an uncertain outcome.
Credits per million actual input tokens: Jev, Kev, Tev1, Microsoft-Decision-1, Drex, Liquid d1, Perplexity Decider V1 and Clef Flash: 600; Solar Decide and Flash: 720; Decider V1.1, Mercury Decide and Span-01: 300; GPT-6 Luna Decisions: 1,500; Clef Omni: 2,200; Clef: 3,500. Laya, Mercury Decide :free and both Span-01 Lite variants: 1 credit per successful request. $1 buys 10,000 credits. Rates round up per request with a 1-credit minimum. Web, API and evaluation share these rates. Output is not charged; failed calls release the reservation. Estimates exclude taxes.
Data & history
Saved configurations and web request bodies/results are private to your account. API history retains metadata, token usage and credits, not request content. Browser drafts are local to this browser. Embedded image pixels are omitted from drafts, configurations and history; metadata and missing-image counts remain. Add the images again before replaying. API URL references may expire. API setup exports local-file code without storing pixels.
Recipes
Support routing
Route billing, technical, and account requests; keep an explicit fallback.
Open recipe ↗Agent routing
Choose a deterministic lookup, a model, or human review.
Open recipe ↗Citation verification
Check a claim against its source, including missing and conflicting evidence.
Open recipe ↗Test the same cases against two rule sets
Capture A from the current workbench model and rules. Change the model or questions, then capture B. Import up to 25 labeled cases and compare both versions. The dataset state replaces each captured state.
{"id":"refund","state":"Please refund my duplicate payment.","expected":{"route":"billing"}}
{"id":"login","state":"My reset link has expired.","expected":{"route":"account"}}1–25 cases. JSONL: one {id, state, expected} per line. CSV: id,state,expected; expected is a JSON object keyed by question ID. Match rate uses labeled answers from completed requests; errors are counted separately. Noul labels are true/false (P(yes) ≥ 0.5). Score uses the tolerance set before the run.