Ir al contenido principal

Guía de integración

Quédate con tu cliente. Cambia la URL base y el valor model.

Los modelos de texto hablan aquí los protocolos que tu SDK ya habla: Chat Completions, el subconjunto sin estado de Responses, Anthropic Messages y Google generateContent. Lo interesante es qué ocurre con un parámetro que el modelo de destino nunca declaró.

El reto

Las capas de compatibilidad suelen mentir por omisión

El fallo clásico no es un 500. Es un parámetro que tu pasarela aceptó, descartó y nunca mencionó: el modelo corrió sin tu temperature, tus definiciones de herramientas o tu formato de respuesta, y la salida pareció simplemente decepcionante en lugar de rota.

01

Un parámetro no declarado se rechaza, no se descarta

messages, tools, tool_choice, response_format, max_tokens, temperature y top_p se asignan a los campos declarados del modelo. El resto se reenvía a su esquema y devuelve 400 si el modelo no lo declara. El silencio nunca es la respuesta.

02

La forma del error sigue al protocolo que llamaste

En /v1 el cuerpo es un objeto de error de OpenAI o Anthropic, no el sobre {code, msg, data, request_id} de /api/v1. Si mezclas ambas superficies, maneja las dos formas.

03

Transmisión y liquidación son cosas distintas

stream: true devuelve eventos chat.completion.chunk terminados con data: [DONE]. El cobro sigue el uso medido, así que un flujo interrumpido no es una petición gratuita.

El enfoque

Cambia el endpoint y vuelve a pasar tus evaluaciones

Cambia base_url y api_key, sustituye la cadena de modelo por un valor de GET /v1/models y ejecuta la batería de pruebas que ya tienes. Si un parámetro devuelve 400, el modelo elegido nunca lo admitió: información que la versión silenciosa jamás te daba.

Sirve cualquier cliente compatible con OpenAI. Solo cambian la URL base y el valor model.

POST /v1/chat/completions

from openai import OpenAI

client = OpenAI(
    base_url="https://api.spicyapi.ai/v1",
    api_key=os.environ["SPICY_API_KEY"],
)

stream = client.chat.completions.create(
    model="<publisher>/<model>/chat",          # exact value from GET /v1/models
    messages=[{"role": "user", "content": "Summarise these notes in three bullets."}],
    temperature=0.7,
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

text/event-stream

data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"- "}}]}
data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"Ships"}}]}
data: [DONE]

Contrato

Lo que conviene fijar desde el principio

API LLM compatible con OpenAI: cambia la URL base — Lo que conviene fijar desde el principio
Campo o cabeceraValor o límite
POST /v1/chat/completionschat.completion · SSE with stream: true
GET /v1/modelsevery callable model value
Authorization: Bearer · x-api-key · x-goog-api-keyaccepted on /v1
undeclared parameter400 · never silently dropped

Desliza horizontalmente para ver todas las columnas.

Integración

De la primera llamada a producción

  1. 01Crea una clave y pide GET /v1/models para ver los identificadores que se pueden llamar ahora mismo.
  2. 02Apunta el cliente a la URL base y envía una primera petición sin transmisión: recibes un objeto chat.completion estándar.
  3. 03Activa la transmisión y comprueba que tu lector maneja chat.completion.chunk y el centinela [DONE].
  4. 04Vigila el uso por clave en la consola y pon un tope diario antes de enviar tráfico de producción.

Encaje

Cuándo este camino es el adecuado

Elígelo si

  • Ya tienes código cliente de OpenAI, Anthropic o Google funcionando y solo quieres cambiar el modelo de detrás.
  • Quieres imagen, vídeo y texto con una clave, un saldo y un mismo juego de topes de gasto.

Busca otra vía si

  • Dependes de hilos o asistentes con estado en el servidor. Aquí se admite el subconjunto sin estado de Responses.
  • Necesitas salidas de medios. Esas pasan por createTask o por la proyección de Videos para clientes que ya hablan esa forma.

Comprobaciones

Lo que puedes verificar tú mismo

Cuatro superficies de protocolo, una clave

/v1/chat/completions, /v1/responses, /v1/messages y /v1beta/models/{model}:generateContent se autentican con la misma clave. Authorization: Bearer, x-api-key y x-goog-api-key se aceptan allí donde el SDK los espera.

La lista de modelos es el contrato

GET /v1/models devuelve exactamente los identificadores que aceptan todas las operaciones /v1 y /api/v1, con el creador en owned_by. Los precios salen de /api/v1/models, específico de la cuenta y por tanto privado.

Validación, límites y reservas son compartidos

La capa de compatibilidad reutiliza la misma autenticación, los mismos límites de tasa, la misma validación, el mismo cálculo de precio y la misma reserva que la superficie nativa. Solo cambia el sobre.

Antes del lanzamiento

Comportamientos de la plataforma que conviene confirmar

  • Mantén la clave en el servidor; una credencial en la cadena de consulta nunca se acepta.
  • Registra en cada llamada el identificador de respuesta propio del protocolo para tener un asidero ante cualquier consulta.
  • Decide antes del lanzamiento cómo llega a tus usuarios un 400 por un parámetro no admitido.
  • Pon topes diario, mensual y acumulado por clave en lugar de confiar solo en el saldo.

Preguntas frecuentes

Lo que más se pregunta en esta página

Cualquier cliente que permita fijar URL base y cadena de modelo. Los clientes con forma de OpenAI usan /v1/chat/completions y /v1/responses, los de Anthropic /v1/messages y los de Google GenAI las rutas generateContent.

Siguiente paso

Apuntar un cliente a un modelo de texto

Apunta un cliente de OpenAI, Anthropic o Google a SpicyAPI. Qué pasa tal cual, qué se rechaza a propósito y cómo se cobra el texto.

Guías relacionadas