Gemini
Llama a Gemini a mitad de precio con su API nativa, el SDK Google Gen AI o Gemini CLI: generateContent, streaming SSE, thinking y countTokens.
Half Off Dev expone los métodos propios de Gemini, generateContent, streamGenerateContent y countTokens, bajo /v1beta/models/{model}. Dale al SDK Google Gen AI la URL base https://halfoff.dev y tu clave de Half Off Dev como API key, y tu código de Gemini sigue funcionando a mitad del precio de lista. Los cuerpos se reenvían sin cambios, así que la referencia de la API de Google describe cada campo.
Configura el SDK#
Los SDK se autentican con x-goog-api-key. También se acepta el parámetro de consulta ?key=.
curl "https://halfoff.dev/v1beta/models/gemini-3.1-pro:generateContent" \
-H "x-goog-api-key: $HALFOFF_API_KEY" \
-H "content-type: application/json" \
-d '{
"contents": [{"role": "user", "parts": [{"text": "Resume qué aporta una CDN a un blog pequeño."}]}]
}'Instálalo con pip install google-genai o npm install @google/genai. Los ids de modelo salen de GET /v1/models, y las grafías de Google como gemini-3.1-pro-preview llevan al mismo modelo. Si quieres la lista con la forma de respuesta de Gemini, llama a GET /v1beta/models.
Streaming con server-sent events#
Pide :streamGenerateContent?alt=sse para recibir SSE. Cada evento es un GenerateContentResponse parcial, y el último trae el usageMetadata completo. Los SDK añaden alt=sse por su cuenta.
curl -N "https://halfoff.dev/v1beta/models/gemini-3-flash:streamGenerateContent?alt=sse" \
-H "x-goog-api-key: $HALFOFF_API_KEY" \
-H "content-type: application/json" \
-d '{"contents": [{"role": "user", "parts": [{"text": "Escribe un poema de cuatro versos sobre compiladores."}]}]}'Sin alt=sse, el método envía un único array JSON en streaming. Funciona, pero SSE es más fácil de procesar por partes y es el único modo en el que el gateway puede mandar un evento de error en condiciones si el stream se queda colgado. Consulta Streaming.
Instrucciones de sistema y thinking#
systemInstruction, generationConfig, safetySettings y las declaraciones de funciones en tools pasan exactamente como las documenta Google. Los modelos Gemini 3 piensan por defecto; ajústalo con thinkingConfig siguiendo la guía de thinking de Google.
response = client.models.generate_content(
model="gemini-3.1-pro",
contents="Propón un plan semanal para aprender Rust en dos meses.",
config=types.GenerateContentConfig(
system_instruction="Eres un mentor de programación práctico. Usa viñetas.",
max_output_tokens=4096,
),
)
print(response.text)
print(response.usage_metadata)El pensamiento aparece como usageMetadata.thoughtsTokenCount y se cobra a la tarifa de salida junto con candidatesTokenCount. Igual que en la API de Google, los resúmenes de pensamiento llegan como partes marcadas con "thought": true solo si pones generationConfig.thinkingConfig.includeThoughts: true; si no, la respuesta no contiene partes de pensamiento.
Contar tokens#
:countTokens recibe los mismos contents con los que generarías y devuelve totalTokens. Es gratis y funciona con saldo cero. Tómalo como aproximado: sirve para compararlo con la ventana de contexto, no para prever el cargo al céntimo.
curl "https://halfoff.dev/v1beta/models/gemini-3.1-pro:countTokens" \
-H "x-goog-api-key: $HALFOFF_API_KEY" \
-H "content-type: application/json" \
-d '{"contents": [{"role": "user", "parts": [{"text": "Mide esta frase."}]}]}'Gemini CLI#
Gemini CLI toma el endpoint y la clave de variables de entorno:
export GOOGLE_GEMINI_BASE_URL=https://halfoff.dev
export GEMINI_API_KEY="$HALFOFF_API_KEY"
gemini -m gemini-3.1-proLa guía completa está en Gemini CLI.
Caché#
Gemini guarda en caché automáticamente los prefijos repetidos (caché implícita). Los tokens cacheados aparecen en usageMetadata.cachedContentTokenCount y se cobran a la tarifa de lectura de caché. Cada conversación vuelve al mismo canal para que esa caché siga caliente; consulta Caché de prompts.
No soportado#
Estas funciones de la API de Gemini devuelven 404: cachedContents (caché de contexto explícita), subida de archivos, embedContent y batchEmbedContents, el modo batch y la Live API.
Cabeceras de la petición#
| Cabecera | Comportamiento |
|---|---|
x-goog-api-key | Tu clave de Half Off Dev. También valen Authorization: Bearer y ?key=. |
x-halfoff-group | Opcional. Elige el grupo de canales para esta petición, salvo que la clave ya esté vinculada a uno. |
x-session-id | Opcional. Marca peticiones como una misma conversación para el enrutamiento según caché. |
Los errores usan la forma de Gemini, {"error": {"code": 429, "message": "...", "status": "RESOURCE_EXHAUSTED"}}; consulta Errores.