Para usar la API de decisiones de OpenAI, envía una solicitud POST a https://api.openai.com/v1/decisions con "model": "gpt-6-luna", una input (texto, imágenes o ambos), y un array de questions donde cada pregunta es un predicate, un choice o un score. Obtienes respuestas tipadas con probabilidades en lugar de texto para analizar, y pagas $0.10 por 1 millón de tokens de entrada, sin cargos por salida, lectura de caché o escritura de caché. El endpoint está en beta pública a partir del 6 de octubre de 2026.
Esta guía cubre cómo obtener una clave, la primera llamada en curl, Python y JavaScript, la lectura de cada tipo de respuesta, tres preguntas en un mismo ticket de soporte, la entrada de imágenes, los umbrales y una configuración de pruebas en Apidog. Para saber cuándo elegir el endpoint, empieza con qué es la API de decisiones de OpenAI.
Solicitud a la API de Decisiones de un vistazo
| Campo | Lo que acepta |
|---|---|
model |
gpt-6-luna (el único modelo disponible en beta) |
input |
Una cadena, o un array de mensajes user cuyo content es una cadena o partes de tipo input_text y input_image |
questions[].type |
predicate, choice o score |
questions[].instructions |
Obligatorio; la pregunta en palabras sencillas |
questions[].name |
Opcional; se devuelve en la respuesta (null si se omite) |
questions[].choices |
Solo choice; de 2 a 255 objetos {value, description} únicos, value una cadena o booleano |
questions[].levels |
Solo score; objetos {label, description} ordenados, el más bajo primero, índices desde 0 |
safety_identifier |
ID opcional opaco del usuario final, hasta 128 caracteres |
Fuente: la referencia de la API de Decisiones. Este endpoint no tiene temperature, stream, tools ni text.format.
Obtener una clave y hacer la primera llamada
Crea una clave en el panel de control de OpenAI (la guía de claves de API de OpenAI lo cubre), expórtala como OPENAI_API_KEY y nunca la pegues en el código. Luego, haz una pregunta de sí/no:
curl https://api.openai.com/v1/decisions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna",
"input": "The box arrived crushed and the screen is cracked.",
"questions": [
{"type": "predicate", "name": "damaged",
"instructions": "Does the customer report a damaged item?"}
]
}'
La respuesta tiene tres campos de nivel superior: model, answers y usage. Esta es la forma de la referencia de OpenAI, con output_tokens en 0 porque el endpoint no cobra por la salida:
{
"model": "gpt-6-luna",
"answers": [
{"type": "predicate", "name": "damaged", "probability": 0.95}
],
"usage": {
"input_tokens": 42,
"input_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0},
"output_tokens": 0,
"output_tokens_details": {"reasoning_tokens": 0},
"total_tokens": 42
}
}
La misma llamada en Python (SDK 3.26.0 o posterior):
from openai import OpenAI
client = OpenAI() # lee OPENAI_API_KEY del entorno
decision = client.decisions.create(
model="gpt-6-luna",
input="The box arrived crushed and the screen is cracked.",
questions=[
{"type": "predicate", "name": "damaged",
"instructions": "Does the customer report a damaged item?"}
],
)
print(decision.answers[0].probability)
Y en JavaScript (SDK 7.30.0 o posterior):
import OpenAI from "openai";
const client = new OpenAI();
const decision = await client.decisions.create({
model: "gpt-6-luna",
input: "The box arrived crushed and the screen is cracked.",
questions: [
{ type: "predicate", name: "damaged",
instructions: "Does the customer report a damaged item?" },
],
});
console.log(decision.answers[0].probability);
Leer la respuesta por tipo
Las respuestas se devuelven en el orden en que las hiciste, cada una con un type. Actúa según el tipo, porque cualquier pregunta puede ser una refusal.
predicatedevuelveprobability, una estimación de 0 a 1 de que la condición es verdadera.choicedevuelvechoice(elvalueganador),probabilitiescomo un array de objetos{value, probability}, yconfidence.scoredevuelvescore,probabilitiescomo un array de objetos{value, label, probability}(dondevaluees el índice de nivel basado en 0), yconfidence. La puntuación es el promedio ponderado por la probabilidad de los índices de nivel, por lo que puede situarse entre niveles: 1.1 significa "entre el nivel 1 y el nivel 2, cerca del 1".refusaldevuelve solotypeyname. El modelo rechazó esa pregunta; otras preguntas en la misma solicitud aún pueden recibir respuestas.
for a in decision.answers:
if a.type == "refusal":
send_to_review(a.name)
elif a.type == "predicate":
flag = a.probability > 0.9
elif a.type == "choice":
route = a.choice if a.confidence > 0.8 else "review"
elif a.type == "score":
priority = round(a.score)
La guía de OpenAI lo explica de esta manera: choice para categorías sin un orden, como departamentos; score para niveles ordenados, como la gravedad.
Tres preguntas en un mismo ticket de soporte
Las preguntas independientes comparten una solicitud y una input, y cada pregunta puede usar un tipo diferente. Aquí hay un predicate, un choice y un score en un solo ticket:
{
"model": "gpt-6-luna",
"input": "I was charged twice for my order.",
"questions": [
{"type": "predicate", "name": "refund_requested",
"instructions": "Is the customer asking for money back?"},
{"type": "choice", "name": "department",
"instructions": "Which team should handle this ticket?",
"choices": [
{"value": "billing", "description": "Charges, refunds, invoices"},
{"value": "technical", "description": "Bugs and errors in the product"},
{"value": "shipping", "description": "Delivery and tracking"},
{"value": "other", "description": "Anything else"}
]},
{"type": "score", "name": "urgency",
"instructions": "How urgent is this ticket?",
"levels": [
{"label": "low", "description": "No time pressure"},
{"label": "medium", "description": "Needs a reply this week"},
{"label": "high", "description": "Customer is blocked or losing money"}
]}
]
}
El array answers se devuelve en el mismo orden. Los valores choice siguientes son los valores de guía de OpenAI para esta entrada exacta; los valores de predicate y score son ilustrativos:
"answers": [
{"type": "predicate", "name": "refund_requested", "probability": 0.88},
{"type": "choice", "name": "department", "choice": "billing",
"probabilities": [
{"value": "billing", "probability": 0.95},
{"value": "technical", "probability": 0.02},
{"value": "shipping", "probability": 0.01},
{"value": "other", "probability": 0.02}
],
"confidence": 0.93},
{"type": "score", "name": "urgency", "score": 1.6,
"probabilities": [
{"value": 0, "label": "low", "probability": 0.05},
{"value": 1, "label": "medium", "probability": 0.30},
{"value": 2, "label": "high", "probability": 0.65}
],
"confidence": 0.65}
]
Dos reglas de la guía: incluye una opción de reserva como other cuando tus categorías no cubren todas las entradas, y escribe preguntas basadas en criterios observables para que los niveles de puntuación adyacentes signifiquen cosas diferentes. Si una segunda decisión depende de la primera respuesta, envía una solicitud separada.
Entrada de imagen
Pasa una imagen como parte del contenido dentro de un mensaje user. La guía documenta las URLs de datos base64 en línea:
{
"model": "gpt-6-luna",
"input": [{
"role": "user",
"content": [
{"type": "input_text", "text": "Photo attached to a return request."},
{"type": "input_image", "image_url": "data:image/jpeg;base64,/9j/4AAQ..."}
]
}],
"questions": [
{"type": "predicate", "name": "visible_damage",
"instructions": "Is the product visibly damaged?"}
]
}
La referencia de la API también enumera URLs HTTP(S) de acceso público, hasta 128 imágenes en todos los mensajes en una solicitud, y un campo detail opcional (low, high, auto, original), así que prueba las URLs alojadas con tu propia cuenta antes de confiar en ellas. Las entradas file_id no son compatibles en ninguna de las páginas.
Elegir umbrales a partir de ejemplos etiquetados
OpenAI no publica cifras de precisión o calibración para el endpoint. Su guía es usar ejemplos etiquetados de tu propia aplicación para establecer umbrales de enrutamiento, filtrado o revisión, basándose en el costo de los falsos positivos versus los falsos negativos. En la práctica, esto significa un pequeño CSV de tickets reales con el departamento que un humano eligió, ejecutado a través de la misma solicitud, para que puedas ver dónde confidence separa las rutas claras de aquellas que necesitan una persona. La siguiente sección construye ese bucle.
Probar la API de Decisiones en Apidog
Las solicitudes guardadas hacen que el ajuste de umbrales y las comprobaciones de regresión sean repetibles. Aquí está la configuración en Apidog:
- Almacena la clave como una variable de entorno. Crea un entorno, añade
OPENAI_API_KEYcomo una variable secreta (la guía de entornos y variables secretas de Apidog muestra la configuración), y establece el encabezadoAuthorizationcomoBearer {{OPENAI_API_KEY}}. La clave nunca se incluye en un cuerpo de solicitud compartido. - Guarda una solicitud por tipo de pregunta. Crea una POST a
https://api.openai.com/v1/decisionsconContent-Type: application/json, pega la preguntachoicedel ejemplo de ticket anterior de forma independiente y guárdala. Duplícala para las versiones de predicate y score. - Añade aserciones JSONPath. En la solicitud de
choice: el estado es 200,$.answers[0].typees igual achoice,$.answers[0].choicees igual abilling,$.answers[0].confidencees mayor que 0.8, y$.usage.output_tokenses igual a 0. Para el predicate de daño, afirma que$.answers[?(@.name=='damaged')].probabilityes mayor que 0.9. Un cambio de redacción en tus instrucciones, o un cambio de comportamiento del modelo, ahora fallará una prueba en lugar de enrutar incorrectamente los tickets. - Ejecútalo sobre tickets etiquetados. Construye un escenario de prueba a partir de la solicitud guardada y adjunta un pequeño CSV con dos columnas,
ticket_textyexpected_department. Mapea{{ticket_text}}ainputy afirma que$.answers[0].choicees igual a{{expected_department}}. El informe de ejecución muestra laconfidencepara cada fila, que son los datos que OpenAI te dice que uses para establecer los umbrales. El punto por debajo del cual se encuentran todas las rutas incorrectas se convierte en tu umbral de "enrutamiento automático" en el código. - Simula el array
answerspara el frontend. Apunta el router o la interfaz de usuario a una simulación del mismo endpoint que devuelve una respuestachoiceconconfidencepor encima y por debajo de tu umbral, más unrefusal, para que la ruta de la cola de revisión se construya antes de que gastes un token de entrada. Las respuestas simuladas condicionales en Apidog cubren la activación de simulaciones según el contenido de la solicitud. - Ejecuta el escenario en CI. Exporta un token de acceso y luego añade un paso a tu pipeline:
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t "$SCENARIO_ID" -e "$ENV_ID" -r cli,junit
Una aserción fallida detiene la compilación, por lo que una caída silenciosa en la confidence se detecta antes del despliegue en lugar de en la cola de soporte. Para patrones más amplios, consulta pruebas de aplicaciones LLM.
Manejar errores y casos extremos
- 429 límite de tasa excedido. No se publican límites específicos para Decisiones; consulta Configuración > Organización > Límites para conocer tus cifras. Retrocede exponencialmente y respeta un encabezado
Retry-Aftersi está presente. La guía de límite de tasa excedido tiene un envoltorio de reintento. - Respuestas de rechazo (Refusal). Trata
type: "refusal"como un resultado de enrutamiento, no como una excepción. Envía ese ticket a un humano y conserva las otras respuestas de la misma solicitud. - Decisiones dependientes. Cada pregunta se evalúa de forma independiente contra la entrada compartida. Cualquier cosa que dependa de una respuesta anterior necesita su propia solicitud.
Preguntas frecuentes
¿Cuánto cuesta la API de Decisiones? $0.10 por 1 millón de tokens de entrada en gpt-6-luna, sin cargos por salida, lectura de caché o escritura de caché. Un ticket de 500 tokens con tres preguntas cuesta 500 / 1,000,000 x $0.10 = $0.00005, por lo que un millón de dichos tickets cuestan $50. La entrada de contexto largo de más de 272K tokens es 2x, y el procesamiento regional añade un 10%.
¿La API de Decisiones es gratuita? No. No hay un nivel gratuito para Decisiones. Si quieres probar GPT-6 Luna sin pagar, la publicación rutas gratuitas de GPT-6 Luna enumera lo que existe.
¿Qué tan rápida es? OpenAI dice que es aproximadamente 10 veces más rápida que la API de Respuestas y no publica ninguna cifra de latencia absoluta. Un desarrollador en el foro de OpenAI informó decisiones de imagen en aproximadamente 0.8 segundos.
¿Qué modelos funcionan con la API de Decisiones? Solo gpt-6-luna hoy. Es un endpoint en Luna, no un modelo separado. Consulta qué es GPT-6 Luna para el modelo en sí.
¿Cuándo debería usar Structured Outputs en su lugar? Cuando necesites un objeto en tu propio esquema JSON, como campos extraídos o una explicación escrita, o la llamada a funciones cuando el modelo deba solicitar una herramienta con argumentos. La publicación API de Decisiones vs API de Respuestas muestra el mismo ticket realizado de ambas maneras.
¿Cómo se compara con Jev? Ambas devuelven respuestas tipadas con probabilidades y solo cobran la entrada; Jev es solo texto a $0.042 por 1 millón. La comparación API de Decisiones vs Jev tiene la tabla completa.
Siguiente paso
Envía la solicitud de ticket de tres preguntas de esta guía, luego ejecútala sobre 20 de tus propios tickets etiquetados y observa dónde la confidence separa las rutas correctas de las incorrectas. Luego descarga Apidog para mantener la solicitud, el escenario CSV y las aserciones juntos, de modo que el umbral que elijas hoy se vuelva a verificar en cada despliegue.
