Skip to content

Decisions

POST /v1/decisions is for model calls that exist to make a decision: route a ticket, check whether a message is urgent, score a passage, classify a record. Instead of prose you have to parse, you get typed answers with probabilities to set thresholds on. It follows OpenAI's Decisions API.

Decision models include gpt-6-luna-decisions and microsoft-decision-1.

Ask questions

curl https://api.cloakray.com/v1/decisions \
  -H "Authorization: Bearer $CLOAKRAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna-decisions",
    "input": "Help! My payouts have been failing for 3 days.",
    "questions": [
      {
        "type": "choice",
        "name": "department",
        "instructions": "Which team should handle this?",
        "choices": [
          { "value": "billing", "description": "Payments, invoicing, refunds" },
          { "value": "technical", "description": "Bugs, outages, integrations" }
        ]
      },
      { "type": "predicate", "name": "is_urgent", "instructions": "Does this convey urgency?" },
      {
        "type": "score",
        "name": "impact",
        "instructions": "Rate the operational impact.",
        "levels": [{ "label": "None" }, { "label": "Limited" }, { "label": "Critical" }]
      }
    ]
  }'

Question types

TypeAsksAnswer
predicateWhether something is trueprobability from 0 to 1
choiceWhich of your choices applieschoice, a probability per option, and confidence
scoreA rating on your ordered levels, lowest firstscore, probabilities, and confidence

The response

{
  "model": "gpt-6-luna-decisions",
  "answers": [
    {
      "type": "choice",
      "name": "department",
      "choice": "billing",
      "probabilities": [
        { "value": "billing", "probability": 0.88 },
        { "value": "technical", "probability": 0.12 }
      ],
      "confidence": 0.81
    },
    { "type": "predicate", "name": "is_urgent", "probability": 0.93 },
    { "type": "score", "name": "impact", "score": 1.7, "confidence": 0.74 }
  ]
}

Answers come back in the order you asked, each with its question's name. A choice keeps the type of the value you gave — string or boolean. A question the model declines comes back as {"type": "refusal", "name": ...} while the others are still answered.

Using the answers

const byName = Object.fromEntries(result.answers.map((answer) => [answer.name, answer]));

if (byName.is_urgent.probability > 0.8) escalate(ticket);
route(ticket, byName.department.choice);

Set thresholds from your own data: label a few hundred examples, look at the probabilities, and pick the cut-off that balances misses against false alarms.

Pricing

Decisions are billed on input tokens; the answers themselves carry no output charge. Prices are on each model's page.