Api.Airforce
API REFERENCE

Finalizaciones de chat

Genera respuestas de chat en más de 100 modelos desde una sola API. Directamente compatible con OpenAI Chat Completions, Anthropic Messages y Anthropic Responses.

Airforce habla tanto el formato OpenAI Chat Completions como el formato Anthropic Messages sobre el mismo conjunto de modelos. Elige el SDK que ya uses y solo cambia la base URL — los modelos que no son de Claude se reenvían de forma transparente detrás de cualquiera de las dos superficies.

Esta página cubre la autenticación, las estructuras de request y response para ambas superficies, streaming, tool calling, vision, reasoning y prompt caching. ¿Eres nuevo aquí? Empieza con el ejemplo básico de abajo, haz que funcione una llamada y luego añade streaming, tools o caching una vez que lo logres.

Autenticación

Cada solicitud necesita un token Bearer (tu clave API de Airforce). La cabecera de Anthropic x-api-key también se acepta en /v1/messages para compatibilidad con SDK.

Authorization: Bearer sk-air-YOUR_API_KEY
# alt for /v1/messages:
x-api-key: sk-air-YOUR_API_KEY

POST /v1/chat/completions

Finalizaciones de chat compatibles con OpenAI. Trabaja con el funcionario. openai SDK anulando base_url a https://api.airforce/v1.

POSThttps://api.airforce/v1/chat/completions

Cuerpo de la solicitud

ParameterTypeRequiredDescription
modelstringRequiredIdentificación del modelo. Utilice GET /v1/models para descubrir los ID disponibles.
messagesarrayRequiredHistorial de la conversación. Cada entrada tiene { role: "system" | "user" | "assistant" | "tool", content }. El contenido es una cadena o un array de bloques de contenido (visión, ver más abajo).
max_tokensintegerOptionalNúmero máximo de tokens a generar. Limitado a los max_output_tokens del modelo.
temperaturefloatOptionalTemperatura de muestreo, 0–2. Más baja es más determinista. El valor predeterminado depende del proveedor upstream.
top_pfloatOptionalMuestreo de núcleos. Utilice temperatura o top_p, no ambos.
streambooleanOptionalCuando es verdadero, la respuesta es una secuencia de eventos enviados por el servidor. Consulte "Transmisión" a continuación.
modelsarrayOptionalFallback models (max 3), e.g. ["deepseek-v3.2", "gpt-4o-mini"]. If every channel of the primary model fails, each candidate is tried in order. You are billed for — and response.model reports — the model that actually answered. Unknown or plan-gated candidates are skipped. With the OpenAI SDK pass it via extra_body.
transformsarrayOptionalPrompt transforms. Supported: ["middle-out"] — when the conversation overflows the model's context window, whole messages are dropped from the middle (system prompts, the first message and the most recent turns are kept), so long roleplay or agent histories keep working instead of erroring. Opt-in; off by default.
stream_optionsobjectOptional{ include_usage: boolean }. El uso siempre se incluye en el último fragmento del stream; este campo se acepta por compatibilidad con OpenAI, pero no se puede desactivar.
stopstring | arrayOptionalHasta 4 secuencias de parada. La generación se detiene tan pronto como se produce una.
toolsarrayOptionalDefiniciones de funciones que el modelo puede llamar. Consulte "Llamada de herramientas" a continuación.
tool_choicestring | objectOptional"auto" (predeterminado), "none" o { type: "function", function: { name } } para forzar una llamada específica.
response_formatobjectOptional{ type: "json_object" } obliga al modelo a emitir JSON válido. Ignorado para modelos que no lo admiten.
reasoning_effortstringOptionalProfundidad de razonamiento estilo OpenAI o1/o3: "low" | "medium" | "high". Consulta "Razonamiento y pensamiento".
thinkingstring | objectOptionalConmutador de pensamiento entre proveedores. "on" | "off" | "auto", o el formato de Anthropic { type: "enabled", budget_tokens: N }. Consulta "Razonamiento y pensamiento".
thinking_budgetintegerOptionalLímite de token para el seguimiento de razonamiento del modelo (cuando el proveedor expone uno).
ignore_defaultsbooleanOptionalOmita los parámetros predeterminados por modelo guardados por el usuario (configurados en el panel) para esta solicitud.

Ejemplo básico

curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.1-chat",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "What is the capital of France?"}
    ],
    "max_tokens": 200,
    "temperature": 0.7
  }'

Forma de respuesta

ParameterTypeRequiredDescription
idstringOptionalID de finalización estable, p. "chatcmpl-abc123".
objectstringOptional"chat.completion" para no transmitidos, "chat.completion.chunk" para transmitidos.
createdintegerOptionalMarca de tiempo Unix (segundos).
modelstringOptionalEco del ID del modelo solicitado.
choicesarrayOptionalArray de candidatos de finalización: [{ index, message: { role, content, tool_calls? }, finish_reason }].
choices[].finish_reasonstringOptional"stop" | "length" | "tool_calls" | "content_filter".
usageobjectOptional{ prompt_tokens, completion_tokens, total_tokens, completion_tokens_details?, prompt_tokens_details?, cache_creation_input_tokens?, cache_creation? }. completion_tokens_details.reasoning_tokens se establece cuando el modelo produjo un rastro de razonamiento. Los campos de caché aparecen cuando el upstream devolvió información de caché de prompt: prompt_tokens_details.cached_tokens reporta lecturas de caché (estándar OpenAI), cache_creation_input_tokens agrega las escrituras, y cache_creation.ephemeral_5m_input_tokens / ephemeral_1h_input_tokens dan el desglose por TTL.
{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1710000000,
  "model": "gpt-5.1-chat",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "The capital of France is Paris."
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 20,
    "completion_tokens": 8,
    "total_tokens": 28
  }
}

Razonamiento y pensamiento

Los modelos que apoyan el razonamiento extendido exponen un rastro de pensamiento junto con el resultado regular. Airforce normaliza tres convenciones ascendentes diferentes en un conjunto de parámetros canónicos que funcionan en todas partes.

Controlar supports_reasoning: true en un modelo en GET /v1/models para saber qué ID aceptan estos parámetros.

Modelos con apoyo al razonamiento.

· live

Parámetros canónicos

ParameterTypeRequiredDescription
reasoning_effortstringOptional"bajo" | "medio" | "alto". OpenAI o1/o3, modelos de razonamiento GPT-5 y cualquier enrutador que se asigne a ellos.
thinkingstring | objectOptional"on" | "off" | "auto" para un cambio rápido, o { type: "enabled", budget_tokens: N } para el formato nativo de Anthropic. Se corresponde con el pensamiento extendido de Claude, el pensamiento de Gemini y el razonamiento de DeepSeek.
thinking_budgetintegerOptionalTokens máximos que el modelo puede gastar razonando antes de emitir resultados visibles. Refleja los tokens_de_presupuesto.

Esfuerzo de razonamiento (estilo OpenAI)

curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "o3-mini",
    "messages": [{"role": "user", "content": "Prove the Pythagorean theorem."}],
    "reasoning_effort": "high"
  }'

Pensamiento extendido (estilo Anthropic)

curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4.6",
    "messages": [{"role": "user", "content": "Plan a 7-day Italy trip."}],
    "thinking": {"type": "enabled", "budget_tokens": 4000}
  }'

La propia huella del razonamiento aparece en choices[0].message.reasoning (forma OpenAI) o como thinking bloques en content (formato de Anthropic). Los tokens de razonamiento se facturan y reportan en usage.completion_tokens_details.reasoning_tokens.

Ese desglose completion_tokens_details.reasoning_tokens solo está presente cuando el proveedor upstream lo informa. En una respuesta en stream la traza llega en delta.reasoning_content por chunk.


Entrada de visión e imagen

Modelos con supports_vision: true aceptar imágenes incrustadas como bloques de contenido. Funciona una URL pública o una URL de datos base64; Los límites de tamaño dependen del modelo anterior.

Modelos con soporte de visión.

· live
curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.1-chat",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "What is in this image?"},
        {"type": "image_url", "image_url": {"url": "https://example.com/cat.jpg"}}
      ]
    }]
  }'

Llamada de herramientas

Modelos con supports_tools: true Puede llamar a funciones que usted defina. El modelo devuelve un tool_calls formación; ejecuta la llamada y luego envía el resultado de vuelta en un tool mensaje.

Modelos con soporte de llamada de herramientas.

· live

Pedido

curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.1-chat",
    "messages": [{"role": "user", "content": "What is the weather in Paris?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather for a location",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "City name"}
          },
          "required": ["location"]
        }
      }
    }],
    "tool_choice": "auto"
  }'

Respuesta con llamada de herramienta

{
  "id": "chatcmpl-abc123",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_1",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"location\":\"Paris\"}"
        }
      }]
    },
    "finish_reason": "tool_calls"
  }]
}

Seguimiento con el resultado de la herramienta.

{
  "model": "gpt-5.1-chat",
  "messages": [
    {"role": "user", "content": "What is the weather in Paris?"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_1",
        "type": "function",
        "function": {"name": "get_weather", "arguments": "{\"location\":\"Paris\"}"}
      }]
    },
    {"role": "tool", "tool_call_id": "call_1", "content": "{\"temp_c\": 14, \"sky\": \"cloudy\"}"}
  ]
}

Structured outputs

Set response_format to make the model return JSON. Two modes are supported:

  • { "type": "json_object" } — the response is a single valid JSON value.
  • { "type": "json_schema", "json_schema": { "name", "schema", "strict" } } — the model is steered to produce JSON that matches your JSON Schema.
curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.1-chat",
    "messages": [{"role": "user", "content": "Extract the city and country: I live in Paris, France."}],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "location",
        "schema": {
          "type": "object",
          "properties": { "city": {"type": "string"}, "country": {"type": "string"} },
          "required": ["city", "country"]
        }
      }
    }
  }'

Reliability: even when a model wraps its answer in prose or a markdown code fence, Airforce extracts the JSON payload so you always receive parseable content. If no valid JSON can be recovered, the original text is returned unchanged — so the guarantee never makes a response worse. This applies to non-streamed responses; streamed responses are passed through unchanged.


Transmisión

Colocar stream: true para recibir finalizaciones parciales como eventos enviados por el servidor. Cada evento es un fragmento JSON con la misma forma que la respuesta no transmitida, excepto message es reemplazado por delta. La corriente termina con data: [DONE].

curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.1-chat",
    "messages": [{"role": "user", "content": "Write a haiku about Berlin."}],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'

Formato de cable

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1710000000,"model":"gpt-5.1-chat","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1710000000,"model":"gpt-5.1-chat","choices":[{"index":0,"delta":{"content":"Cold "},"finish_reason":null}]}

data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1710000000,"model":"gpt-5.1-chat","choices":[{"index":0,"delta":{"content":"stone "},"finish_reason":null}]}


data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1710000000,"model":"gpt-5.1-chat","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":12,"completion_tokens":17,"total_tokens":29}}

data: [DONE]

POST /v1/messages

API de mensajes compatible con Anthropic. Trabaja con el funcionario. @anthropic-ai/sdk estableciendo baseURL a https://api.airforce. Reenvía a OpenAI/Google/etc. de forma transparente para modelos que no son Claude.

POSThttps://api.airforce/v1/messages

Cuerpo de la solicitud

ParameterTypeRequiredDescription
modelstringRequiredID del modelo (formato de Anthropic o alias enrutado).
messagesarrayRequiredCada entrada: { role: "user" | "assistant", content: string | array }.
max_tokensintegerRequiredRequerido por Anthropic. Límite de token para la respuesta.
systemstring | arrayOptionalPrompt del sistema. Pasa un array de bloques { type: "text", text, cache_control? } para marcar segmentos de prefijo en caché. Consulta "Prompt caching".
temperaturefloatOptional0–1.
top_pfloatOptionalMuestreo de núcleos.
top_kintegerOptionalLimite el grupo de muestreo a los K tokens principales.
stop_sequencesarrayOptionalHasta 4 secuencias de parada.
streambooleanOptionalCuando es verdadero, emite un flujo de eventos SSE estilo Anthropic (consulta "Streaming").
fallbacksarrayOptionalFallback models (max 3) in Anthropic form: [{"model": "gpt-4o-mini"}]. If every channel of the primary model fails, each candidate is tried in order; you are billed for — and the response model field reports — the model that actually answered. A plain models string array is accepted too.
toolsarrayOptionalDefiniciones de herramientas de Anthropic: { name, description, input_schema }. La respuesta puede contener bloques de contenido tool_use.
tool_choiceobjectOptional{ type: "auto" | "any" | "tool", name? }.
thinkingobjectOptionalPensamiento extendido de Anthropic: { type: "enabled", budget_tokens: N }.

Ejemplo

curl https://api.airforce/v1/messages \
  -H "x-api-key: sk-air-YOUR_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4.6",
    "max_tokens": 256,
    "system": "You are a helpful assistant.",
    "messages": [
      {"role": "user", "content": "Hello, Claude!"}
    ]
  }'

Forma de respuesta

ParameterTypeRequiredDescription
idstringOptionalID de mensaje, p.e. "msg_01ABCxyz".
typestringOptionalSiempre "message".
rolestringOptionalSiempre "assistant".
contentarrayOptionalArray de bloques de contenido: { type: "text" | "tool_use" | "thinking", … }.
modelstringOptionalEco del modelo solicitado.
stop_reasonstringOptional"end_turn" | "max_tokens" | "stop_sequence" | "tool_use".
usageobjectOptional{ input_tokens, output_tokens, cache_read_input_tokens?, cache_creation_input_tokens?, cache_creation? }. Los campos de caché aparecen cuando se usó caché de prompt. cache_creation.ephemeral_5m_input_tokens y ephemeral_1h_input_tokens dan el desglose de escritura por TTL.

Transmisión de eventos

Anthropic SSE utiliza eventos con nombre en lugar de fragmentos JSON únicos. Cada evento tiene tanto un event: nombre y un data: Carga útil JSON.

event: message_start
data: {"type":"message_start","message":{"id":"msg_01","role":"assistant","content":[],"model":"claude-sonnet-4.6","stop_reason":null,"usage":{"input_tokens":12,"output_tokens":1}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":17}}

event: message_stop
data: {"type":"message_stop"}

POST /v1/messages/count_tokens

Anthropic-compatible token counting. Send the same system / messages / tools you would pass to /v1/messages and get an input-token estimate back without running the model — nothing is billed.

POSThttps://api.airforce/v1/messages/count_tokens
curl https://api.airforce/v1/messages/count_tokens \
  -H "x-api-key: sk-air-YOUR_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4.6",
    "system": "You are a helpful assistant.",
    "messages": [{"role": "user", "content": "Hello, Claude!"}]
  }'

# → {"input_tokens": 34}

The count is a fast character-based estimate (about 4 characters per token) over system, messages and tools — close enough for context-budget checks, not an exact tokenizer run.


Almacenamiento en caché rápido

En /v1/messages con los modelos Claude, marque un prefijo como almacenado en caché pasando system como una matriz de bloques donde el segmento almacenado en caché lleva cache_control: { type: "ephemeral" }. Las solicitudes posteriores que comienzan con el mismo prefijo cobran la tarifa de lectura de caché más económica. Modelos con supports_caching: true en /v1/models apoyar esto.

Modelos con almacenamiento en caché rápido

· live
{
  "model": "claude-sonnet-4.6",
  "max_tokens": 1024,
  "system": [
    {"type": "text", "text": "You are a senior staff engineer at Airforce."},
    {
      "type": "text",
      "text": "<repository-snapshot>...</repository-snapshot>",
      "cache_control": {"type": "ephemeral"}
    }
  ],
  "messages": [
    {"role": "user", "content": "Where is rate limiting enforced?"}
  ]
}

Cómo se reportan los conteos de caché en la respuesta

Los conteos de tokens de caché se devuelven en la forma nativa de cada formato, así los SDKs (openai, @anthropic-ai/sdk, @google/genai) los leen sin código personalizado. Los campos se omiten cuando el valor es cero, manteniendo las respuestas no cacheadas ligeras.

/v1/chat/completions (forma OpenAI)

"usage": {
  "prompt_tokens": 2104,
  "completion_tokens": 147,
  "total_tokens": 2251,
  "prompt_tokens_details": { "cached_tokens": 1980 },
  "cache_creation_input_tokens": 124,
  "cache_creation": {
    "ephemeral_5m_input_tokens": 124,
    "ephemeral_1h_input_tokens": 0
  }
}

/v1/messages (forma Anthropic)

"usage": {
  "input_tokens": 2104,
  "output_tokens": 147,
  "cache_read_input_tokens": 1980,
  "cache_creation_input_tokens": 124,
  "cache_creation": {
    "ephemeral_5m_input_tokens": 124,
    "ephemeral_1h_input_tokens": 0
  }
}

/v1beta/.../generateContent (forma Gemini)

"usageMetadata": {
  "promptTokenCount": 2104,
  "candidatesTokenCount": 147,
  "totalTokenCount": 2251,
  "cachedContentTokenCount": 1980
}

Dónde se aplica el caché

Los marcadores cache_control explícitos se respetan en /v1/messages y /v1/chat/completions para modelos Claude — colócalos en bloques de contenido system o message. Muchos otros proveedores (familia OpenAI, DeepSeek, Gemini) cachean automáticamente: no envías marcadores y simplemente ves cached_tokens en la respuesta cuando se reutiliza un prefijo suficientemente largo.

Duración del caché: 5 minutos o 1 hora

Un prefijo cacheado vive 5 minutos por defecto y el temporizador se reinicia en cada acierto. Para un prefijo más duradero, añade ttl: "1h" al marcador. La respuesta informa cada TTL por separado bajo cache_creation.

"cache_control": { "type": "ephemeral", "ttl": "1h" }

Ejemplo: primero escritura, luego lectura

Envía exactamente la misma solicitud dos veces (el ejemplo de caché de arriba). La primera llamada que ve el prefijo paga una escritura de caché única; las llamadas idénticas dentro de la TTL pagan la lectura de caché mucho más barata.

Primera llamada — escritura de caché (extracto de usage):

"usage": {
  "input_tokens": 2104,
  "output_tokens": 12,
  "cache_creation_input_tokens": 1980,
  "cache_read_input_tokens": 0
}

Segunda llamada idéntica dentro de la TTL — lectura de caché:

"usage": {
  "input_tokens": 2104,
  "output_tokens": 12,
  "cache_creation_input_tokens": 0,
  "cache_read_input_tokens": 1980
}

Límites y coste

  • Claude requiere un prefijo cacheable mínimo (unos 1024 tokens; más en algunos modelos). Los prefijos más cortos simplemente no se cachean.
  • Hasta 4 puntos de caché por solicitud, y el prefijo cacheado debe ser idéntico byte a byte entre llamadas — incluso un cambio de un carácter falla el caché.
  • Las escrituras de caché cuestan más que la entrada normal (5m ≈ 1,25×, 1h ≈ 2×); las lecturas cuestan mucho menos (≈ 0,1×). Consulta los precios de caché de cada modelo en la página de precios.

POST /v1/responses

Superficie OpenAI Responses-API para conversaciones con estado. Misma autenticación Bearer/x-api-key. Los conteos de caché aparecen como input_tokens_details.cached_tokens (lectura) más el plano cache_creation_input_tokens + cache_creation.ephemeral_* (escrituras) para paridad con /v1/chat/completions.

POSThttps://api.airforce/v1/responses

POST /v1beta/models/{model}:generateContent

Google Gemini-compatible endpoint. Works with the official @google/genai SDK and the Gemini CLI by pointing the base URL at https://api.airforce/v1beta. Any routed model works — requests are translated to and from the native Gemini shape, and the model is taken from the URL path (not the body).

POSThttps://api.airforce/v1beta/models/{model}:generateContent

Authentication

Pass your Airforce API key any of the three ways Google clients use:

# 1) query parameter (Google default)
?key=sk-air-YOUR_API_KEY

# 2) header
x-goog-api-key: sk-air-YOUR_API_KEY

# 3) bearer token
Authorization: Bearer sk-air-YOUR_API_KEY

Request body

ParameterTypeRequiredDescription
contentsarrayRequiredConversation turns. Each: { role: "user" | "model", parts: [...] }. A part is { text }, { functionCall: { name, args } }, or { functionResponse: { name, response } }. "model" is Gemini's term for the assistant role.
systemInstructionobjectOptionalSystem prompt: { parts: [{ text }] }.
generationConfigobjectOptional{ temperature, maxOutputTokens, topP, stopSequences } — mapped to the canonical sampling parameters.
toolsarrayOptionalTool definitions: [{ functionDeclarations: [{ name, description, parameters }] }]. functionDeclarations are flattened across entries.
toolConfigobjectOptionalTool-choice control: { functionCallingConfig: { mode: "AUTO" | "ANY" | "NONE" } }. ANY forces a call, NONE disables tools.

Example

curl "https://api.airforce/v1beta/models/gemini-3.1-pro:generateContent" \
  -H "x-goog-api-key: sk-air-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [
      {"role": "user", "parts": [{"text": "What is the capital of France?"}]}
    ],
    "systemInstruction": {"parts": [{"text": "You are a helpful assistant."}]},
    "generationConfig": {"temperature": 0.7, "maxOutputTokens": 256}
  }'

Response shape

ParameterTypeRequiredDescription
candidatesarrayOptionalGenerated turns: [{ content: { role: "model", parts }, finishReason, index }]. Only the first candidate is populated.
candidates[].finishReasonstringOptional"STOP" | "MAX_TOKENS" | "SAFETY" | "OTHER".
usageMetadataobjectOptional{ promptTokenCount, candidatesTokenCount, totalTokenCount, cachedContentTokenCount? }. cachedContentTokenCount appears when the upstream reported a cache read.
modelVersionstringOptionalEcho of the requested model.
{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [{"text": "The capital of France is Paris."}]
    },
    "finishReason": "STOP",
    "index": 0
  }],
  "usageMetadata": {
    "promptTokenCount": 16,
    "candidatesTokenCount": 8,
    "totalTokenCount": 24
  },
  "modelVersion": "gemini-3.1-pro"
}

POST /v1beta/models/{model}:streamGenerateContent

Streaming uses the :streamGenerateContent action and returns Server-Sent Events. Each data: line is a full Gemini-shaped chunk (not a delta object); the final chunk carries usageMetadata.

data: {"candidates":[{"content":{"role":"model","parts":[{"text":"The capital"}]},"index":0}],"modelVersion":"gemini-3.1-pro"}

data: {"candidates":[{"content":{"role":"model","parts":[{"text":" is Paris."}]},"index":0}],"modelVersion":"gemini-3.1-pro"}

data: {"candidates":[{"content":{"role":"model","parts":[]},"finishReason":"STOP","index":0}],"usageMetadata":{"promptTokenCount":16,"candidatesTokenCount":8,"totalTokenCount":24}}

List models

The catalog is also exposed in Gemini Model-resource shape so Google clients can enumerate models.

curl https://api.airforce/v1beta/models

Notes: the base URL is https://api.airforce/v1beta (or /v1), not Google's host. The model name comes from the URL path, not the request body. Only the first candidate is returned, and a subset of Gemini fields is translated — safetySettings and cachedContent are currently ignored. Billing, rate limits and smart routing apply exactly as on /v1/chat/completions.


Errores

Airforce devuelve códigos de estado HTTP estándar y un sobre de error uniforme para ambos puntos finales.

ParameterTypeRequiredDescription
400invalid_request_errorOptionalJSON con formato incorrecto, falta el campo obligatorio, modelo desconocido.
401invalid_request_error / auth_requiredOptionalClave API faltante o no válida.
402insufficient_quotaOptionalEl modelo requiere una suscripción activa o un saldo Pay-as-you-Go positivo.
403model_access_denied / insufficient_scopeOptionalLos permisos de plan o por clave niegan esta solicitud.
404model_not_foundOptionalEl modelo solicitado no existe o no tienes acceso a él.
429rate_limit_errorOptionalSe superó la tasa de solicitud o el límite de token diario.
503api_error / moderation_unavailableOptionalTodas las claves ascendentes para el proveedor solicitado fallaron.
{
  "error": {
    "message": "The requested model does not exist or you do not have access to it.",
    "type": "model_not_found",
    "param": null,
    "code": "404"
  }
}

El slug descriptivo está en type. code es el estado HTTP como cadena (p. ej. "404"), y param es null excepto en errores de validación de rango de parámetros, donde nombra el parámetro infractor.

Descubre modelos

Consulte la lista completa de ID de modelo y sus indicadores de capacidad (visión, herramientas, razonamiento, almacenamiento en caché, longitud del contexto, etc.) en /docs/api/models.

curl https://api.airforce/v1/models \
  -H "Authorization: Bearer sk-air-YOUR_API_KEY"