Python guide
OpenAI Decisions API in Python
OpenAI has not published an SDK for its Decisions API — there is no client.decisions.create to copy. This page shows working Python for this site's endpoint — a callable OpenAI Decisions API alternative that serves decisions-1 and follows the same constrained-decision pattern.
Updated
Make the call
One POST to /api/v1/decisions with a Bearer key. The body is model, state, and questions — 1 to 6 questions, each typed noul, choice, or score. Set DECISIONS_API_KEY to a key from the dashboard.
Use requests (or httpx for async — the call shape is identical). Keep a timeout on every call; a hung decision should fail fast, not stall the pipeline.
Python
import os
import requests
res = requests.post(
"https://decisions-api.net/api/v1/decisions",
headers={"Authorization": f"Bearer {os.environ['DECISIONS_API_KEY']}"},
json={
"model": "decisions-1",
"state": "I was charged twice for my subscription this morning.",
"questions": {
"refund": {
"type": "noul",
"instructions": "Is the customer asking for money back?",
}
},
},
timeout=30,
)
res.raise_for_status()
answers = res.json()["answers"]
print(answers["refund"]["noul"])Read the probabilities
answers comes back keyed by your question ids. A noul answer is the probability the statement is true. A choice answer carries the winning choice, a probability for every option, and a confidence value — use confidence, not just the winner, to decide whether to auto-act.
Python
answers = res.json()["answers"]
# noul: probability the statement is true
if answers["refund"]["noul"] >= 0.8:
route_to_refunds()
# choice: winning label + per-option probabilities + confidence
team = answers["team"]
print(team["choice"], team["probabilities"], team["confidence"])Timeouts and retries
429 and 502 are worth a short backoff retry — failed calls are not billed. 402 means the balance is empty: top up, do not retry. 422 is a validation error; the message names the field, so fix the body instead of retrying.
Python
import time
import requests
def decide(body, attempts=3):
for i in range(attempts):
try:
res = requests.post(
"https://decisions-api.net/api/v1/decisions",
headers={"Authorization": f"Bearer {os.environ['DECISIONS_API_KEY']}"},
json=body,
timeout=30,
)
if res.status_code in (429, 502):
time.sleep(2 ** i)
continue
if res.status_code == 402:
raise RuntimeError("out of credits")
res.raise_for_status()
return res.json()["answers"]
except requests.Timeout:
time.sleep(2 ** i)
raise RuntimeError("decision call failed")Keep the provider behind one function
Callers should see a function that takes text and returns a label — not HTTP details. When OpenAI opens its Decisions API you swap the inside of decide() and keep every call site unchanged. The question text, options, and thresholds all carry over.
Python
# Keep the decision behind one function. Swap the HTTP layer
# when OpenAI publishes its schema — callers never change.
def route_ticket(text: str) -> str:
answers = decide({
"model": "decisions-1",
"state": text,
"questions": {
"team": {
"type": "choice",
"instructions": "Which team should own this ticket?",
"criteria": {
"payments": "Checkout or billing.",
"frontend": "Rendering or browser behavior.",
"account": "Login or permissions.",
},
}
},
})
team = answers["team"]
return team["choice"] if team["confidence"] >= 0.7 else "triage"FAQ
Is there an official OpenAI SDK example for the Decisions API?
No. OpenAI has not published SDK methods or a request schema for its Decisions API — anything showing client.decisions.create is invented. This page uses plain HTTP, which is what any provider SDK would wrap anyway.
Can I use httpx instead of requests?
Yes — the endpoint is a plain HTTPS POST. Use httpx.AsyncClient with the same headers, body, timeout, and status handling.
How do I send structured context?
state accepts a JSON object or array, not just a string — pass dicts directly in the json body and the model reads them as context.
Run a decision from the browser
Skip the setup — run a real call in the playground with 2 free credits for new visitors.