Las API compatibles con OpenAI ahora tienen dos formatos de solicitud principales: el conocido /v1/chat/completions y el más reciente /v1/responses. GetVibe API acepta ambos con una sola clave y una sola URL base, https://getvibeapi.com/v1. Aquí te explicamos en qué se diferencian en la práctica, cuál elegir y cuál es la única trampa al cambiar de uno a otro.
La versión corta
| Chat Completions | Responses | |
|---|---|---|
| Endpoint | POST /v1/chat/completions | POST /v1/responses |
| Entrada | un array de messages | input: una cadena o un array de elementos |
| Prompt del sistema | un mensaje con el rol system | el campo instructions |
| Respuesta | choices[0].message | un array output: razonamiento, mensaje, llamadas a funciones |
| Límite de salida | max_tokens | max_output_tokens |
| Quién lo usa | la mayoría de los SDK, frameworks y apps de chat | Codex CLI y los SDK de agentes más recientes |
El formato no cambia el modelo, el precio ni el recuento de tokens: se te cobran los tokens de entrada y salida del modelo en ambos casos.
La misma solicitud en ambos formatos
Chat Completions:
curl https://getvibeapi.com/v1/chat/completions \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna",
"messages": [
{"role": "system", "content": "Responde en una sola oración."},
{"role": "user", "content": "¿Qué significa HTTP 429?"}
],
"max_tokens": 300
}'
Responses:
curl https://getvibeapi.com/v1/responses \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna",
"instructions": "Responde en una sola oración.",
"input": "¿Qué significa HTTP 429?",
"max_output_tokens": 300
}'
En Chat Completions, el texto está en choices[0].message.content. En Responses se encuentra dentro de output: en los modelos de razonamiento, el primer elemento es un elemento reasoning y la respuesta es el elemento de tipo message. No tienes que recorrer el array manualmente; el SDK de Python tiene una propiedad output_text.
import os
from openai import OpenAI
client = OpenAI(base_url="https://getvibeapi.com/v1", api_key=os.environ["GETVIBE_API_KEY"])
chat = client.chat.completions.create(
model="gpt-6-luna",
messages=[{"role": "system", "content": "Responde en una sola oración."},
{"role": "user", "content": "¿Qué significa HTTP 429?"}],
)
print(chat.choices[0].message.content)
resp = client.responses.create(
model="gpt-6-luna",
instructions="Responde en una sola oración.",
input="¿Qué significa HTTP 429?",
)
print(resp.output_text)
Responses no está limitado a los modelos de OpenAI. Antes de publicar este artículo, enviamos la misma solicitud de Responses a gpt-6-luna, claude-sonnet-5.5 y deepseek-v4.1-flash, y los tres respondieron. DeepSeek devolvió un elemento reasoning antes de su elemento message, exactamente como se describió arriba.
Historial de la conversación: envíalo tú
Esto es lo único que debes saber antes de cambiar. La propia API de Responses de OpenAI puede mantener una conversación en el servidor, por lo que la siguiente solicitud apunta a la anterior mediante previous_response_id. GetVibe API no almacena tus conversaciones, así que previous_response_id no es compatible y store se ignora. Cuando lo probamos, la solicitud fue rechazada con un error 400.
El patrón que funciona es el mismo que con Chat Completions: envía todo el historial en input.
history = [{"role": "user", "content": "Me llamo Ana. Recuérdalo."}]
first = client.responses.create(model="gpt-6-luna", input=history)
history.append({"role": "assistant", "content": first.output_text})
history.append({"role": "user", "content": "¿Cómo me llamo? Una palabra."})
second = client.responses.create(model="gpt-6-luna", input=history)
print(second.output_text) # Ana
Herramientas: una estructura diferente
Las llamadas a funciones funcionan en ambos formatos, pero la definición de la herramienta tiene un aspecto diferente. En Chat Completions, los campos de la función están anidados dentro de un objeto function; en Responses aparecen directamente en la herramienta. La llamada llega como un elemento function_call independiente, y devuelves el resultado como un elemento function_call_output con el mismo call_id.
import json
tools = [{
"type": "function",
"name": "get_weather",
"description": "Current weather in a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": False,
},
}]
items = [{"role": "user", "content": "¿Qué tiempo hace en Denver?"}]
resp = client.responses.create(model="gpt-6-luna", input=items, tools=tools)
for item in resp.output:
if item.type == "function_call":
result = {"city": "Denver", "temp_f": 54, "sky": "overcast"} # tu función
items.append({"type": "function_call", "call_id": item.call_id,
"name": item.name, "arguments": item.arguments})
items.append({"type": "function_call_output", "call_id": item.call_id,
"output": json.dumps(result)})
final = client.responses.create(model="gpt-6-luna", input=items, tools=tools)
print(final.output_text)
En nuestra prueba, el modelo llamó a get_weather con {"city":"Denver"}, y la segunda solicitud respondió que en Denver había 54 °F y estaba nublado. La versión del mismo ciclo con Chat Completions está en nuestra guía de llamadas a funciones.
Streaming
Ambos formatos admiten "stream": true, pero los eventos son diferentes. Chat Completions envía líneas data: uniformes, con cada nuevo fragmento de texto en choices[0].delta.content. Responses envía eventos con nombre: primero response.created, luego response.output_text.delta con los fragmentos de texto y, al final, response.completed. Si analizas el stream por tu cuenta en lugar de hacerlo mediante un SDK, necesitas un parser para el formato específico.
Cuál elegir
- Chat Completions si ya tienes código que lo usa o si utilizas un framework, una app de chat o una plataforma no-code. Casi todas las herramientas lo admiten, y no hay razón para reescribir código que funciona solo para cambiar de formato.
- Responses si una herramienta lo requiere. El ejemplo principal es Codex CLI, que se comunica con
/v1/responses; la configuración está en la documentación de Codex CLI y en nuestra guía de Codex CLI.
En cualquier caso, la lista de modelos y los precios son los mismos. Consulta la referencia de la API para ver todos los campos y la página de modelos para conocer los precios actuales.
