Referencia de la API
URLs base, cabeceras de autenticación y de respuesta, límites de ritmo y reglas de reintento para usar Claude, GPT y Gemini con Half Off Dev.
Half Off Dev no se inventa una API nueva. Sirve, desde un único host, las tres que tu código y tus SDK ya hablan: Anthropic Messages, OpenAI Chat Completions (y Responses) y Gemini, con una sola clave y un solo saldo prepago. Las peticiones y respuestas siguen el esquema de cada proveedor de modelos, así que a los SDK oficiales solo les cambias la URL base y la clave. Lo que añade Half Off Dev es poco: unas cuantas cabeceras de respuesta, límites por clave y su propia facturación.
Cada petición y respuesta, con ejemplos en cURL, Python y Node.js.
Códigos de estado, cuerpos de error en cada formato y una receta de reintentos.
Dónde va la clave en cada SDK.
Tu primera petición a mitad de precio.
URLs base#
Todo se sirve por HTTPS desde https://halfoff.dev. Configura en tu SDK la URL base de la segunda columna.
| API | URL base del SDK | Endpoints |
|---|---|---|
| Anthropic Messages | https://halfoff.dev | POST /v1/messages, POST /v1/messages/count_tokens |
| OpenAI Chat Completions | https://halfoff.dev/v1 | POST /v1/chat/completions |
| OpenAI Responses (modelos GPT) | https://halfoff.dev/v1 | POST /v1/responses |
| Gemini | https://halfoff.dev | POST /v1beta/models/{model}:generateContent, :streamGenerateContent, :countTokens |
| Lista de modelos | — | GET /v1/models, GET /v1beta/models |
Cualquier otra ruta, como la API de Embeddings de OpenAI, responde 404.
Autenticación#
Todos los endpoints aceptan un token bearer, y también la cabecera propia de cada proveedor, así que cada SDK funciona con su configuración por defecto.
Authorization: Bearer ho-...| Cabecera | La envía |
|---|---|
Authorization: Bearer ho-... | SDK de OpenAI, clientes HTTP genéricos |
x-api-key: ho-... | SDK de Anthropic |
x-goog-api-key: ho-... | SDK Google Gen AI |
La lista de modelos es pública; todo lo demás requiere clave. Detalles en Autenticación.
Formato de peticiones y respuestas#
- JSON en ambos sentidos. Envía los cuerpos en JSON con
content-type: application/json; las respuestas también son JSON. - Streaming. Las peticiones de Anthropic y OpenAI con
"stream": trueresponden con server-sent events (text/event-stream). El:streamGenerateContentde Gemini devuelve un array JSON en streaming, o server-sent events si añades?alt=sse, igual que la API de Google. Consulta Streaming. - CORS está abierto a cualquier origen. Eso no convierte en buena idea llamar desde el navegador: una clave en el código front-end es una clave que cualquiera puede copiar.
Cabeceras de respuesta#
Además de las cabeceras propias del proveedor, las respuestas de los modelos incluyen:
| Cabecera | Significado |
|---|---|
x-halfoff-request-id | ID único de la llamada, visible en Logs. Indícalo a soporte. |
x-halfoff-group | Grupo de canales que atendió la llamada |
x-halfoff-channel | Etiqueta breve de ese grupo, codificada para URL |
x-halfoff-queued-ms | Milisegundos que la llamada esperó por capacidad (solo si esperó) |
retry-after | En respuestas 429: segundos que debes esperar antes de reintentar |
Versiones#
Cada API conserva el versionado de su proveedor. Envía lo que envía tu SDK: anthropic-version y anthropic-beta para Anthropic, openai-beta para OpenAI; Gemini usa la ruta /v1beta, como la API de Google. Half Off Dev reenvía esas cabeceras y ninguna otra cabecera de proveedor, así que una función que dependa de otra cabecera distinta no estará disponible.
Las respuestas pueden ganar campos con el tiempo. Escribe clientes que ignoren los campos que no conozcan.
Límites de ritmo#
| Límite | Se aplica a | Al superarlo |
|---|---|---|
| Peticiones por minuto y concurrencia definidas en una clave | Las peticiones de esa clave | 429 con retry-after |
| Capacidad del modelo | Todas las peticiones a modelos. Una ráfaga corta espera primero unos segundos en cola. | 429, normalmente con retry-after |
Más en Límites y conmutación por error y Claves de API.
Reintentos e idempotencia#
Cuando un canal falla, Half Off Dev prueba la petición en otros canales antes de rendirse, así que un 5xx que te llega ya se ha reintentado. Aun así, reintenta 429 y 5xx por tu lado con backoff exponencial y respeta retry-after. Los demás 4xx requieren cambiar la petición, no repetirla. Los SDK oficiales de Anthropic y OpenAI reintentan dos veces por defecto; sube max_retries (maxRetries en Node.js) para trabajos por lotes largos.
No hay claves de idempotencia, y eso importa en un caso: una petición que agotó el tiempo en tu lado puede haber terminado y haberse cobrado. Si la repites, puedes pagar dos veces. Da a las generaciones largas un timeout de cliente amplio, o usa streaming. Listar modelos y contar tokens se puede repetir siempre sin riesgo.
Tienes funciones de reintento listas para usar en Errores.
Errores#
Los errores llegan en el formato del endpoint al que llamaste, así que cada SDK lanza la excepción que lanzaría normalmente. Por ejemplo, una petición en formato OpenAI con una clave revocada recibe:
{"error": {"message": "Invalid or revoked API key", "type": "authentication_error", "code": "authentication_error"}}Todos los códigos de estado, con ejemplos de cuerpo en cada formato, están en Errores.