As APIs compatíveis com OpenAI agora têm dois formatos principais de solicitação: o já conhecido /v1/chat/completions e o mais recente /v1/responses. O GetVibe API aceita ambos com uma única chave e uma única URL base, https://getvibeapi.com/v1. Veja como eles diferem na prática, qual escolher e qual é a única armadilha ao migrar de um para o outro.
A versão curta
| Chat Completions | Responses | |
|---|---|---|
| Endpoint | POST /v1/chat/completions | POST /v1/responses |
| Entrada | um array messages | input: uma string ou um array de itens |
| Prompt do sistema | uma mensagem com a função system | o campo instructions |
| Resposta | choices[0].message | um array output: raciocínio, mensagem, chamadas de função |
| Limite de saída | max_tokens | max_output_tokens |
| Quem usa | a maioria dos SDKs, frameworks e apps de chat | Codex CLI e SDKs de agentes mais recentes |
O formato não altera o modelo, o preço nem a contagem de tokens: você paga pelos tokens de entrada e saída do modelo de qualquer forma.
A mesma solicitação nos dois 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": "Responda em uma frase."},
{"role": "user", "content": "O que 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": "Responda em uma frase.",
"input": "O que significa HTTP 429?",
"max_output_tokens": 300
}'
No Chat Completions, o texto está em choices[0].message.content. No Responses, ele fica dentro de output: para modelos de raciocínio, o primeiro item é um item reasoning e a resposta é o item do tipo message. Você não precisa percorrer o array manualmente; o SDK do Python tem uma propriedade 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": "Responda em uma frase."},
{"role": "user", "content": "O que significa HTTP 429?"}],
)
print(chat.choices[0].message.content)
resp = client.responses.create(
model="gpt-6-luna",
instructions="Responda em uma frase.",
input="O que significa HTTP 429?",
)
print(resp.output_text)
O Responses não se limita aos modelos da OpenAI. Antes de publicar, enviamos a mesma solicitação Responses para gpt-6-luna, claude-sonnet-5.5 e deepseek-v4.1-flash, e os três responderam. O DeepSeek retornou um item reasoning antes do message, exatamente como descrito acima.
Histórico da conversa: envie você mesmo
Esta é a única coisa que você precisa saber antes de mudar. A própria API Responses da OpenAI pode manter uma conversa no servidor, então a próxima solicitação aponta para a anterior usando previous_response_id. O GetVibe API não armazena suas conversas, portanto previous_response_id não é compatível e store é ignorado. Quando testamos, a solicitação foi rejeitada com um erro 400.
O padrão funcional é o mesmo do Chat Completions: envie todo o histórico em input.
history = [{"role": "user", "content": "Meu nome é Ana. Lembre-se dele."}]
first = client.responses.create(model="gpt-6-luna", input=history)
history.append({"role": "assistant", "content": first.output_text})
history.append({"role": "user", "content": "Qual é o meu nome? Uma palavra."})
second = client.responses.create(model="gpt-6-luna", input=history)
print(second.output_text) # Ana
Ferramentas: um formato diferente
A chamada de funções funciona nos dois formatos, mas a definição da ferramenta tem uma aparência diferente. No Chat Completions, os campos da função ficam aninhados dentro de um objeto function; no Responses, eles ficam diretamente na ferramenta. A chamada chega como um item function_call separado, e você retorna o resultado como um item function_call_output com o mesmo 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": "Qual é o clima em 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"} # sua função
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)
Em nosso teste, o modelo chamou get_weather com {"city":"Denver"}, e a segunda solicitação respondeu que Denver estava a 54°F e nublado. A versão do Chat Completions do mesmo loop está em nosso guia de chamadas de função.
Streaming
Os dois formatos são compatíveis com "stream": true, mas os eventos diferem. O Chat Completions envia linhas data: uniformes, com cada novo trecho de texto em choices[0].delta.content. O Responses envia eventos nomeados: response.created primeiro, response.output_text.delta com os trechos de texto e response.completed no final. Se você analisar o stream por conta própria, em vez de usar um SDK, precisará de um analisador para o formato específico.
Qual escolher
- Chat Completions se você já tem código usando esse formato ou se usa um framework, um app de chat ou uma plataforma no-code. Quase todas as ferramentas o utilizam, e não há motivo para reescrever um código funcional apenas para mudar de formato.
- Responses se uma ferramenta exigir esse formato. O principal exemplo é o Codex CLI, que se comunica com
/v1/responses; a configuração está na documentação do Codex CLI e em nosso guia do Codex CLI.
De qualquer forma, a lista de modelos e os preços são os mesmos. Consulte a referência da API para ver todos os campos e a página de modelos para conferir os preços atuais.
