NuevoConecta cualquier agente a UberLLM: una clave, todos los modelos, a precio de lista o menos.
UberLLM

Responses API

POST https://api.uberllm.dev/v1/responses ofrece la Responses API de OpenAI en cada modelo de chat del catálogo. Úsala desde el OpenAI SDK (client.responses.create), Codex CLI, o cualquier aplicación con un modo "Responses". Las solicitudes pasan por el mismo enrutamiento, reintentos, límites de clave y facturación que /v1/chat/completions, y cada llamada aparece en Dashboard → Activity con su costo.

curl https://api.uberllm.dev/v1/responses \
  -H "Authorization: Bearer $UBERLLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "instructions": "Answer in one short sentence.",
    "input": "What is the capital of France?"
  }'
from openai import OpenAI

client = OpenAI(base_url="https://api.uberllm.dev/v1", api_key="ull_...")
r = client.responses.create(model="deepseek/deepseek-v4.1-flash", input="Say hi")
print(r.output_text)

Sin estado almacenado

UberLLM no guarda las respuestas para que puedas continuar más tarde. Cada respuesta tiene "store": false, y envías la conversación completa en input en cada llamada: mensajes de usuario anteriores, los elementos de salida del modelo y los resultados de tus herramientas. Codex CLI ya funciona de esta manera.

Estos son rechazados con un 400 (code: unsupported_parameter) que nombra el campo:

  • previous_response_id y conversation
  • background: true
  • input items de tipo item_reference
  • plantillas de prompt almacenadas (prompt)

GET /v1/responses/{id} y las otras rutas de respuesta almacenada no existen.

Solicitud

Campo Qué sucede
model Cualquier id de modelo de chat, alias o sufijo :floor / :nitro, como en las finalizaciones de chat.
input Una string, o una lista de ítems (abajo).
instructions Enviado al modelo como el mensaje del sistema.
stream true para eventos enviados por el servidor.
max_output_tokens El límite de salida.
temperature, top_p, seed, stop Pasados al modelo.
tools, tool_choice, parallel_tool_calls Ver Herramientas abajo.
reasoning.effort Pasado como el esfuerzo de razonamiento del modelo (modelos que piensan).
text.format text, json_object, o json_schema (salida estructurada).
metadata Tus propias etiquetas, mostradas en la fila de Actividad, como en las finalizaciones de chat.
provider, models Opciones de enrutamiento de UberLLM, como en las finalizaciones de chat (Modelos y enrutamiento).
store, include, prompt_cache_key, service_tier, truncation Aceptados y no usados. El razonamiento cifrado siempre es devuelto.

Ítems de entrada

Ítem Se convierte en
message con rol user, assistant, system o developer Un mensaje de chat. developer se envía como system. Partes del contenido input_text, output_text, input_image (image_url: una URL https o data:) y input_file (file_data o file_url).
function_call La llamada a la herramienta del asistente, mantenida en orden.
function_call_output El resultado de la herramienta. Las imágenes en una salida se envían en el siguiente turno del usuario.
custom_tool_call, custom_tool_call_output Una llamada a una herramienta personalizada (de formato libre), y su resultado.
reasoning El razonamiento anterior del modelo, devuelto al modelo en el siguiente turno.
web_search_call y otros registros de herramientas alojadas Omitidos.

Los id son aceptados e ignorados. file_id (archivos subidos) no es compatible en input_image / input_file: envía el archivo en línea o por URL.

Herramientas

  • function: {"type": "function", "name", "description", "parameters", "strict"}. La llamada del modelo regresa como un elemento function_call con call_id, name y arguments (una cadena JSON). Responda con un elemento function_call_output que contenga el mismo call_id.
  • custom (entrada de formato libre, como apply_patch de Codex): al modelo se le proporciona la herramienta con una entrada de cadena, y la gramática en format.definition como su descripción. La llamada regresa como un elemento custom_tool_call con el input en bruto.
  • namespace (herramientas MCP de Codex): cada herramienta interna se ofrece al modelo bajo su espacio de nombres y nombre unidos (mcp__github__get_issue); la llamada regresa con name y namespace divididos de nuevo.
  • Herramientas alojadas (web_search, file_search, code_interpreter, image_generation, computer_use, mcp) se ejecutan en los propios servidores de OpenAI. Se excluyen de la solicitud y el modelo responde sin ellas.

tool_choice acepta "auto", "none", "required", o {"type": "function", "name": "…"}.

Respuesta

{
  "id": "resp_…",
  "object": "response",
  "created_at": 1793333237,
  "status": "completed",
  "model": "deepseek/deepseek-v4.1-flash",
  "output": [
    {"type": "reasoning", "id": "rs_…", "summary": [],
     "content": [{"type": "reasoning_text", "text": "…"}], "encrypted_content": "ull1:…"},
    {"type": "message", "id": "msg_…", "status": "completed", "role": "assistant",
     "content": [{"type": "output_text", "text": "Paris.", "annotations": []}]},
    {"type": "function_call", "id": "fc_…", "status": "completed",
     "call_id": "call_…", "name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}
  ],
  "usage": {
    "input_tokens": 43, "input_tokens_details": {"cached_tokens": 0},
    "output_tokens": 23, "output_tokens_details": {"reasoning_tokens": 0},
    "total_tokens": 66, "cost_usd": 0.0000184
  },
  "store": false
}
  • Un elemento reasoning aparece cuando el modelo devuelve su razonamiento. Envíalo de vuelta en la siguiente input tal cual: encrypted_content contiene el razonamiento para que los modelos que lo necesiten en el siguiente turno lo obtengan.
  • status es incomplete cuando la respuesta alcanzó max_output_tokens (incomplete_details.reason: "max_output_tokens") o un filtro de contenido ("content_filter").
  • usage.cost_usd es lo que se facturó por la llamada. Las respuestas no-streaming también lo llevan en el encabezado X-UberLLM-Cost-USD, y cada respuesta tiene X-Request-Id, el ID de su fila de Actividad.
  • La configuración que enviaste (instructions, tools, temperature, max_output_tokens…) se devuelve como lo hace OpenAI.

Streaming

Con "stream": true la respuesta son eventos enviados por el servidor, cada uno con type y un sequence_number que comienza en 0:

  1. response.created, response.in_progress
  2. Para cada elemento de salida: response.output_item.added, luego sus deltas, luego response.output_item.done con el elemento terminado:
    • texto: response.content_part.added, response.output_text.delta…, response.output_text.done, response.content_part.done
    • razonamiento: response.reasoning_text.delta…, response.reasoning_text.done
    • llamada a función: response.function_call_arguments.delta…, response.function_call_arguments.done
    • llamada a herramienta personalizada: response.custom_tool_call_input.done
  3. response.completed (o response.incomplete) con la respuesta completa y su usage, incluyendo cost_usd.

Mientras un modelo lento se está iniciando, : ping líneas de comentario mantienen la conexión abierta. Cada cliente SSE las omite.

Errores

Una solicitud rechazada antes de que el stream comience recibe un estado HTTP y el sobre de error de OpenAI, el mismo que chat completions (401, 402 sin crédito, 404 modelo desconocido, 429; ver Errores). Si algo falla después de que el stream ha comenzado, termina con response.failed, cuyo response.error tiene code y message. Un stream que se detiene antes de que el modelo termine también finaliza con response.failed, nunca con response.completed, para que los clientes reintenten en lugar de quedarse con media respuesta.