Chat
Chat completions
La API Chat Completions de OpenAI, para todos los modelos de texto: la misma petición y la misma respuesta, el mismo streaming, los mismos SDK.
/v1/chat/completionsPetición
modelstringobligatorio- Un ID de modelo de la página de modelos, como
claude-opus-5-5ogpt-6-sol. messagesarrayobligatorio- La conversación: mensajes
system(odeveloper),user,assistantytool.contentes una cadena, o un array de partes para añadir imágenes, PDF, audio o vídeo. streamboolean- Envía la respuesta como server-sent events mientras se escribe. Consulta Streaming más abajo.
stream_optionsobject{ "include_usage": true }añade un fragmento final con el uso de tokens.max_completion_tokensinteger- El máximo de tokens a generar, razonamiento incluido.
max_tokenstambién funciona. temperaturenumber- De 0 a 2. Más bajo es más centrado, más alto más variado. Algunos modelos de razonamiento lo ignoran. Claude desde Opus 4.7 en adelante (Opus 5 y 5.5, Fable 5 y 5.1, Sonnet 5.5, Haiku 5.5) no lo acepta, así que lo omitimos en esos modelos.
top_pnumber- Muestreo de núcleo, de 0 a 1. Cambia este parámetro o temperature, no ambos. Se omite en los mismos modelos Claude, igual que top_k en ellos y en Muse Wonder.
stopstring | array- Hasta 4 secuencias en las que se detiene la generación.
toolsarray- Funciones que el modelo puede llamar. Consulta Llamada a herramientas más abajo.
tool_choicestring | objectauto,none,requiredo una función concreta. Cuando el laboratorio de un modelo rechaza o ignora una opción (una herramienta forzada en Claude Opus 5.5, Sonnet 5.5 y Fable 5.1; cualquier cosa salvoautoen Muse Wonder;noneen algunos modelos Gemini, DeepSeek Flash, MiMo, HY4 y MiniMax), la enviamos en una forma que el modelo respeta y le indicamos al modelo lo que pediste; una función forzada por nombre va como la única ofrecida.response_formatobject- Salida JSON:
{ "type": "json_object" }, ojson_schemacon un esquema. Consulta Salida estructurada más abajo. reasoning_effortstring- Cuánto razona un modelo de razonamiento:
none,minimal,low,medium,high,xhighomax. Cada modelo acepta algunos de estos (consulta Razonamiento más abajo); otro nivel se ejecuta en el más cercano que acepte. Más alto razona más tiempo y cuesta más tokens de salida. seedinteger- Reproducibilidad en la medida de lo posible, para los modelos que la admiten.
modelsarray- Enrutamiento inteligente para esta petición: alternativas que probar, en orden, si el modelo está caído. Consulta Enrutamiento inteligente.
user y metadata, que se quedan con nosotros. Qué parámetros respeta un modelo (herramientas, esquemas JSON, razonamiento) depende del modelo, igual que con su propio laboratorio. Con el SDK de Python de OpenAI, envía models como extra_body={"models": [...]}.Respuesta
{ "id": "chatcmpl-AbC123...", "object": "chat.completion", "created": 1790870400, "model": "claude-opus-5-5", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Here's the summary..." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 1204, "completion_tokens": 312, "total_tokens": 1516, "prompt_tokens_details": { "cached_tokens": 1024 }, "completion_tokens_details": { "reasoning_tokens": 128 } }}modeles el modelo que respondió. Es el que pediste, salvo que el enrutamiento inteligente haya respondido con una alternativa.- Los modelos de razonamiento pueden añadir
reasoning_contental mensaje: el razonamiento del modelo, cuando lo comparte. usagees lo que se te factura.cached_tokensson tokens de entrada leídos de la caché de prompts del modelo, facturados al precio de caché donde el modelo lo tenga.
Todas las respuestas incluyen además estas cabeceras:
Streaming
Con stream: true, la respuesta llega como server-sent events en el formato de fragmentos de OpenAI, terminando con data: [DONE]. Todos los SDK los leen por ti.
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)stream = client.chat.completions.create( model="claude-sonnet-5-5", messages=[ { "role": "user", "content": "Write a limerick about databases." } ], stream=True, stream_options={ "include_usage": True },)for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True)- No se envía ninguna respuesta hasta que el modelo ha producido su primer token, así que un reintento o un cambio a otra ruta pasa inadvertido para ti.
- Los tramos de silencio (un modelo razonando entre pasos) se rellenan con líneas de comentario SSE (
: keep-alive) cada 15 segundos. Los clientes las ignoran; evitan que los proxies cierren la conexión. Si el primer token tarda más de 20 segundos (un prompt largo, o una ruta que se bloqueó y está siendo reemplazada), el stream se abre entonces: las cabeceras y los comentarios de keep-alive llegan mientras esperas. Cada ruta tiene hasta 3 minutos para arrancar (5 con un nivel de razonamiento alto) antes de probar la siguiente, así que configura el timeout de tu cliente a 10 minutos. - Un stream que se abrió antes de su primer token solo incluye
x-zurelay-modelcuando ningún otro modelo puede responderla (enrutamiento inteligente desactivado), y un error posterior a su apertura llega como un evento de error en el stream (con la misma forma que el cuerpo del error) en lugar de un estado de error. - Con
include_usage, el último fragmento antes de[DONE]tiene una listachoicesvacía y elusage.
Llamadas a herramientas
Describe funciones en tools; cuando el modelo quiere una, responde con tool_calls en lugar de texto. Ejecuta la función, envía el resultado de vuelta como mensaje tool con el ID de la llamada, y el modelo continúa.
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)response = client.chat.completions.create( model="gpt-6-sol", messages=[ { "role": "user", "content": "What's the weather in Lisbon right now?" } ], tools=[ { "type": "function", "function": { "name": "get_weather", "description": "Current weather for a city", "parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": [ "city" ] } } } ],)print(response.choices[0].message.content)Salida estructurada
Pide JSON con response_format. Un json_schema obliga a los modelos que lo admiten a seguir tu esquema; json_object pide cualquier JSON válido (indícalo también en tu prompt).
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)response = client.chat.completions.create( model="gpt-6.1-sol", messages=[ { "role": "user", "content": "Extract the people: 'Ana met Ben and Chloe in Porto.'" } ], response_format={ "type": "json_schema", "json_schema": { "name": "people", "schema": { "type": "object", "properties": { "names": { "type": "array", "items": { "type": "string" } } }, "required": [ "names" ] } } },)print(response.choices[0].message.content)Razonamiento
Los modelos de razonamiento piensan antes de responder. Configura reasoning_effort para cambiar velocidad y coste por profundidad: un nivel más alto piensa más tiempo, tarda más y usa más tokens de salida. Cada modelo acepta los niveles que documenta su laboratorio, desde none (sin pensar) pasando por minimal, low, medium, high y xhigh (extra alto) hasta max; la tabla de abajo los enumera. Si lo omites, el modelo usa su nivel por defecto. Funciona igual con cualquier OpenAI SDK, y puedes probar cada nivel en el Playground del panel.
from openai import OpenAIclient = OpenAI(base_url="https://api.zurelay.com/v1", api_key="YOUR_ZURELAY_KEY")response = client.chat.completions.create( model="zurelay-auto", reasoning_effort="high", messages=[{"role": "user", "content": "How many primes are there below 1,000?"}],)message = response.choices[0].messageprint(getattr(message, "reasoning_content", None)) # the thinking, when the model shares itprint(message.content)El razonamiento vuelve junto con la respuesta en message.reasoning_content (al hacer streaming, en delta.reasoning_content) en los modelos que lo comparten; algunos llaman al campo reasoning. Se factura como tokens de salida y siempre forma parte de completion_tokens; completion_tokens_details.reasoning_tokens lo cuenta aparte cuando el modelo lo informa. Con un esfuerzo alto, una respuesta puede tardar minutos en empezar, así que dale a tu cliente un timeout generoso (consulta Fiabilidad y timeouts).
Niveles de cada modelo
Según la documentación de cada laboratorio. Si un modelo no acepta un nivel, se ejecuta en el más cercano que sí acepta (si hay dos igual de cercanos, el inferior; y el razonamiento solo se desactiva cuando envías none), así que una misma petición funciona en todos los modelos, incluido el enrutado inteligente. La cabecera de respuesta x-zurelay-reasoning-effort indica qué nivel se ejecutó. Una palabra que no sea un nivel se rechaza con un 400 que enumera los niveles del modelo.
El razonamiento de Claude
A través de este endpoint, Claude acepta reasoning_effort como cualquier otro modelo: low, medium, high, xhigh o max (Opus 4.6 no tiene xhigh). En el formato propio de Anthropic, Claude razona de forma adaptativa según un nivel: envía thinking: { type: "adaptive", display: "summarized" } con output_config: { effort: "xhigh" } y lee los bloques de razonamiento. Consulta Anthropic Messages.
¿Tienes dudas o falta algo? Escribe a nuestro equipo de soporte y te responderemos por email, normalmente en menos de un minuto.