KovAPIKovAPI
POST https://kovapi.com/v1/chat/completions

API de chat Gemini 3.1 Pro (Google), modelo multimodal insignia con gran capacidad de razonamiento y de programación y una ventana de contexto de aproximadamente 1M de tokens. Dos niveles de razonamiento: el estándar, que se usa por defecto, es más rápido y razona menos; con reasoning_effort en medium o superior se pasa al nivel de razonamiento alto. Entrada de imágenes; compatible con el SDK de OpenAI.

📥 Ventana de contexto (entrada máxima):~1 000 000 tokens (contexto largo de un millón de tokens).

Probar en el Playground →

Inicio rápido

Dos pasos: envía una petición y luego recibe la respuesta en streaming. Sustituye YOUR_API_KEY por tu clave y los comandos de abajo funcionan tal cual. El endpoint sigue el formato Chat Completions de OpenAI, así que al código de OpenAI que ya tengas solo hay que cambiarle base_url y model.

Paso 1 · Envía una petición

curl
curl https://kovapi.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.1-pro", "messages": [{"role": "user", "content": "Explica la fotosíntesis en una frase"}]}'

Respuesta (HTTP 200)

JSON
{
  "id": "chatcmpl-7f3c9a1e2b4d6f8a",
  "object": "chat.completion",
  "created": 1791281400,
  "model": "gemini-3.1-pro",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "La fotosíntesis es el proceso por el que las plantas usan la luz solar para transformar el dióxido de carbono y el agua en azúcar y liberar oxígeno."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 18,
    "completion_tokens": 42,
    "total_tokens": 60,
    "prompt_tokens_details": {"cached_tokens": 0}
  }
}

message.content es la respuesta. usage recoge los tokens que se cobran en esta petición; prompt_tokens_details.cached_tokens es la parte servida desde la caché, que se cobra al precio de caché.

Paso 2 · Recibe la respuesta en streaming (recomendado)

curl
curl -N https://kovapi.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.1-pro", "stream": true, "messages": [{"role": "user", "content": "Explica la fotosíntesis en una frase"}]}'

El streaming es SSE estándar: cada fragmento lleva texto en choices[0].delta.content, el último fragmento lleva usage y al final llega data: [DONE]. Usa streaming con respuestas largas y con modelos de razonamiento: una petición sin streaming se corta pasados unos 10 minutos.

Python (SDK de OpenAI)

Python
from openai import OpenAI

client = OpenAI(base_url="https://kovapi.com/v1", api_key="YOUR_API_KEY")

# 1. Una petición, una respuesta
resp = client.chat.completions.create(
    model="gemini-3.1-pro",
    messages=[{"role": "user", "content": "Explica la fotosíntesis en una frase"}],
)
print(resp.choices[0].message.content)

# 2. En streaming
stream = client.chat.completions.create(
    model="gemini-3.1-pro",
    messages=[{"role": "user", "content": "Explica la fotosíntesis en una frase"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Autenticación

Header
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Crea una clave API en la consola para empezar.

De un vistazo

Ventana de contexto~1 000 000 tokens
EntradaTexto, imágenes
RazonamientoDos niveles: estándar por defecto; razonamiento alto con reasoning_effort en medium o superior
Llamadas a herramientasSin garantía: tools puede ignorarse y el modelo responde directamente
Búsqueda webSí (web_search: true; la búsqueda en sí es gratis)
Endpoints/v1/chat/completions
StreamingSí (stream: true, SSE)
Forma de cobroPor token: entrada, salida (razonamiento incluido) y aciertos de caché tienen cada uno su precio; los fallos no se cobran

Parámetros de la petición

El cuerpo JSON de POST /v1/chat/completions, igual que en la API Chat Completions de OpenAI. Estos son los parámetros habituales y lo que hace cada uno en este modelo:

ParámetroTipoObligatorioDescripción
modelstringSíEl ID del modelo: gemini-3.1-pro.
messagesarraySíLa conversación: cada mensaje tiene un role (system, user, assistant o tool) y un content. content es una cadena o un array de partes text e image_url (entrada de imágenes; ver más abajo). En conversaciones de varios turnos, envía todo el historial en orden.
streambooleanNoCon true, la respuesta llega en streaming como SSE, con usage en el último fragmento. Por defecto es false.
max_tokensintegerNoEl límite de salida, tokens de razonamiento incluidos. Si es demasiado bajo, el modelo puede agotarlo antes de escribir la respuesta: en ese caso la pasarela devuelve 400 max_tokens_too_small y no cobra nada (se recomienda 512 o más). En algunos modelos, un valor demasiado pequeño se sube automáticamente a un mínimo que deja margen para una respuesta completa, y aun así solo se cobra el uso real.
temperature / top_pnumberNoParámetros de muestreo; se pasan al modelo tal cual (temperature va de 0 a 2). Puede que los modelos de razonamiento no los respeten.
reasoning_effortstringNoElige el nivel: sin enviarlo o con low, nivel estándar; con medium, high o xhigh, nivel de razonamiento alto, que se cobra a su propio precio. También puedes indicarlo en el ID del modelo: gemini-3.1-pro-high.
web_searchbooleanNoCon true, primero se hace una búsqueda web y los resultados se entregan al modelo como referencia; ver más abajo.

Los demás parámetros de OpenAI (como stop, seed o user) se pasan al modelo tal cual; que tengan efecto o no depende del modelo.

Precio

Se cobra por token, a las tarifas vigentes de la tabla de abajo (por millón de tokens). Solo se cobran las peticiones que salen bien, según el uso real: los fallos, los tiempos de espera agotados y los rechazos no se cobran. 1 crédito = $0.005.

TipoUSD / 1M de tokensCréditos / 1M de tokens
Entrada$0.50100
Salida (razonamiento incluido)$3.00600
Acierto de caché$0.0510

Por ejemplo, una petición con 2 000 tokens de entrada y 1 000 tokens de salida (razonamiento incluido) cuesta aproximadamente $0.004.

Razonamiento

Dos niveles: sin indicar el esfuerzo, o con reasoning_effort: "low", se usa el nivel estándar, más rápido y con menos tokens de razonamiento; con medium, high o xhigh, el nivel de razonamiento alto, que razona más a fondo y se cobra a su propio precio (consulta la sección de precio más arriba); las peticiones del nivel de razonamiento alto figuran como gemini-3.1-pro-preview en la facturación y en el registro de llamadas.

El nivel también se puede elegir con el ID del modelo: gemini-3.1-pro-high para el nivel de razonamiento alto y gemini-3.1-pro-low para el nivel estándar.

Los tokens de razonamiento forman parte de usage.completion_tokens y se cobran al precio de salida (algunos modelos los desglosan además en completion_tokens_details.reasoning_tokens).

Caché de prompts

No hace falta ningún parámetro: el proveedor del modelo puede guardar en caché automáticamente un prefijo largo que se repite (el mismo prompt de sistema, los turnos anteriores de una conversación), y la parte en caché se cobra al precio de caché, más bajo. Si se guarda en caché y cuánto lo decide el proveedor; pon al principio de los mensajes lo que nunca cambia para conseguir más aciertos.

El número de tokens en caché llega en usage.prompt_tokens_details.cached_tokens; esa parte se cobra al precio de acierto de caché y el resto de la entrada, al precio de entrada.

Entrada de imágenes

Pon una parte image_url en el array content. Lo recomendado es un data URI en base64 (data:image/png;base64,...), que siempre se puede leer; un enlace público a una imagen hay que descargarlo primero, y de vez en cuando no se consigue o agota el tiempo de espera. Las imágenes cuentan como tokens de entrada según las reglas del fabricante del modelo.

curl
curl https://kovapi.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gemini-3.1-pro", "messages": [{"role": "user", "content": [{"type": "text", "text": "¿Qué hay en esta imagen?"}, {"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."}}]}]}'

Fiabilidad y reintentos automáticos

  • Si una petición da error, agota el tiempo de espera o choca con el límite de capacidad, la pasarela la reintenta automáticamente antes de devolver nada, así que no tienes que reintentar y nunca se cobra dos veces.
  • Cuando un streaming empieza a enviar datos, ya no se reintenta automáticamente: si se corta a medias, se cobra el uso generado hasta ese momento (consulta Facturación y reembolsos).
  • Cuando el modelo está al límite de su capacidad, la pasarela devuelve 429 con Retry-After: espera esos segundos y reintenta. Las peticiones fallidas no se cobran. El estado de cada modelo aparece en la página de estado.

Errores y reembolsos

Los errores llegan como un objeto error (message, type, code, param); decide según el estado HTTP y code, nunca comparando el texto de message. Las peticiones fallidas no se cobran; la lista completa está en Códigos de error.

HTTPcodeCausaQué hacer
400invalid_messages / invalid_role / invalid_max_tokensEn una petición de chat, messages falta, está vacío o tiene un formato incorrecto, un role no es uno de los valores permitidos, o max_tokens no es un entero positivo. param indica el campo.Corrige el campo que indica param.
400model_not_foundEl ID del modelo está mal escrito, falta model, o el modelo no se puede usar en este endpoint (por ejemplo, un modelo de chat en el endpoint de imágenes).Usa un ID de modelo de GET /v1/models o de la referencia de la API.
400max_tokens_too_smallUn modelo de razonamiento gastó todo max_tokens en razonar y no escribió ninguna respuesta (chat sin streaming).Sube max_tokens y reintenta.
400content_filterEl modelo procesó la petición pero no devolvió nada, normalmente porque el contenido activó la política de seguridad del proveedor.Ajusta el prompt y reintenta; el mismo prompt suele volver a rechazarse.
4xxinvalid_requestEl proveedor del modelo rechazó la petición (por ejemplo, por un contexto demasiado largo o un parámetro no admitido); el estado y message se transmiten tal como los envió el proveedor, y code es el valor del proveedor.Modifica la petición según lo que indique message.
401invalid_api_keyLa clave no existe, se eliminó o está desactivada, o la cuenta está desactivada.Revisa la clave en la página API Keys de la consola.
402insufficient_quotaNo hay saldo suficiente para retener el importe de esta petición. La pasarela retiene primero el coste máximo posible de la petición, así que una ráfaga de llamadas simultáneas también puede provocarlo.Si se debe a una ráfaga, espera unos segundos y reintenta; si no, recarga.
403permission_deniedEl modelo no está en la lista de modelos permitidos de la clave.Usa un modelo de la lista o edita la lista en la consola.
429rate_limit_exceededSe superó el límite de peticiones por minuto configurado en esta clave (contado sobre los últimos 60 segundos). Sin cabecera Retry-After.Espera unos segundos y reintenta, o sube el límite de la clave en la consola.
429rate_limit_exceededEl modelo está al límite de su capacidad y la petición no se envió. Solo en los endpoints de chat: los trabajos de imagen y vídeo nunca se rechazan, sino que esperan en cola. Los endpoints compatibles con OpenAI añaden Retry-After.Espera los segundos que indica Retry-After y reintenta.
502upstream_timeoutEl proveedor agotó el tiempo de espera, incluido el caso de tardar demasiado en enviar el primer token.Reintenta; para respuestas largas, usa stream: true.
502upstream_unavailableEl proveedor falló o no está disponible por el momento.Reintenta en breve.
502upstream_busyEl proveedor del modelo está limitando las peticiones. Un 429 del proveedor nunca te llega como 429; en su lugar recibes este 502.Reintenta en breve.
502empty_completionEl proveedor del modelo devolvió un contenido vacío. No es una valoración de tu contenido.Reintenta.
502upstream_prompt_filterLa verificación previa del proveedor bloqueó el prompt. No es una valoración del modelo.Reintenta en breve o cambia un poco la redacción.
503model_maintenanceEl modelo está en mantenimiento y no acepta peticiones; mientras tanto, ningún otro modelo responde en su lugar.Reintenta cuando termine el mantenimiento; consulta el estado del servicio.

Si un streaming falla después de empezar a enviar datos, el código de estado no cambia: el error llega como una línea de datos con error, o el streaming simplemente termina (sin data: [DONE]). Trátalo como interrumpido.