Api.Airforce
API REFERENCE

Completamenti della chat

Genera risposte chat su oltre 100 modelli da un'unica API. Drop-in compatibile con i completamenti della chat OpenAI, i messaggi Anthropic e le risposte Anthropic.

Airforce parla sia il formato OpenAI Chat Completions sia quello Anthropic Messages sullo stesso insieme di modelli. Scegli l'SDK che già usi e cambia soltanto la base URL — i modelli non-Claude vengono inoltrati in modo trasparente dietro entrambe le interfacce.

Questa pagina copre l'autenticazione, la struttura di richiesta e risposta per entrambe le interfacce, lo streaming, il tool calling, la vision, il reasoning e il prompt caching. Sei nuovo qui? Inizia con l'esempio base qui sotto, fai funzionare una chiamata, poi aggiungi streaming, tools o caching una volta che funziona.

Autenticazione

Ogni richiesta necessita di un token Bearer (la tua chiave API Airforce). Anthropic x-api-key viene accettata anche l'intestazione /v1/messages per la compatibilità dell'SDK.

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

POST /v1/chat/completions

Completamenti chat compatibili con OpenAI. Funziona con il funzionario openai SDK eseguendo l'override base_url A https://api.airforce/v1.

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

Richiedi corpo

ParameterTypeRequiredDescription
modelstringRequiredID modello. Utilizza GET /v1/models per scoprire gli ID disponibili.
messagesarrayRequiredCronologia della conversazione. Ogni voce ha { role: "system" | "user" | "assistant" | "tool", content }. Il contenuto è una stringa o un array di blocchi di contenuto (vision, vedi sotto).
max_tokensintegerOptionalNumero massimo di token da generare. Limitato ai max_output_tokens del modello.
temperaturefloatOptionalTemperatura di campionamento, 0–2. Il valore inferiore è più deterministico. L'impostazione predefinita dipende dal provider upstream.
top_pfloatOptionalCampionamento del nucleo. Utilizza temperature o top_p, non entrambi.
streambooleanOptionalQuando è vero, la risposta è un flusso di eventi inviati dal server. Vedere "Streaming" di seguito.
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 }. L’uso è sempre incluso nell’ultimo chunk dello stream; questo campo è accettato per compatibilità con OpenAI ma non può disattivarlo.
stopstring | arrayOptionalFino a 4 sequenze di arresto. La generazione si interrompe non appena ne viene prodotta una.
toolsarrayOptionalDefinizioni di funzioni che il modello può chiamare. Vedere "Chiamata utensile" di seguito.
tool_choicestring | objectOptional"auto" (predefinito), "none", oppure { type: "function", function: { name } } per forzare una chiamata specifica.
response_formatobjectOptional{ type: "json_object" } forza il modello a emettere JSON valido. Ignorato per i modelli che non lo supportano.
reasoning_effortstringOptionalProfondità di ragionamento in stile OpenAI o1/o3: "low" | "medium" | "high". Vedi "Ragionamento e pensiero".
thinkingstring | objectOptionalSwitch di thinking cross-provider. "on" | "off" | "auto", oppure forma Anthropic { type: "enabled", budget_tokens: N }. Vedi "Ragionamento e pensiero".
thinking_budgetintegerOptionalToken cap per la traccia del ragionamento del modello (quando il provider ne espone uno).
ignore_defaultsbooleanOptionalIgnora i parametri predefiniti per modello salvati dall'utente (configurati nel dashboard) per questa richiesta.

Esempio di base

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 della risposta

ParameterTypeRequiredDescription
idstringOptionalID di completamento stabile, ad es. "chatcmpl-abc123".
objectstringOptional"chat.completion" per non in streaming, "chat.completion.chunk" per in streaming.
createdintegerOptionalTimestamp Unix (secondi).
modelstringOptionalEco dell'ID del modello richiesto.
choicesarrayOptionalArray di candidati di completamento: [{ index, message: { role, content, tool_calls? }, finish_reason }].
choices[].finish_reasonstringOptional"fermare" | "lunghezza" | "chiamate_strumento" | "filtro_contenuto".
usageobjectOptional{ prompt_tokens, completion_tokens, total_tokens, completion_tokens_details?, prompt_tokens_details?, cache_creation_input_tokens?, cache_creation? }. completion_tokens_details.reasoning_tokens viene impostato quando il modello ha prodotto una traccia di ragionamento. I campi cache compaiono quando l'upstream ha restituito informazioni sul prompt caching: prompt_tokens_details.cached_tokens riporta le letture cache (standard OpenAI), cache_creation_input_tokens aggrega le scritture, e cache_creation.ephemeral_5m_input_tokens / ephemeral_1h_input_tokens forniscono la suddivisione per 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
  }
}

Ragionamento e pensiero

I modelli che supportano il ragionamento esteso espongono una traccia del pensiero accanto all'output regolare. L'Airforce normalizza tre diverse convenzioni a monte in un insieme di parametri canonici che funzionano ovunque.

Controllo supports_reasoning: true su un modello in GET /v1/models per sapere quali ID accettano questi parametri.

Modelli con supporto del ragionamento

· live

Parametri canonici

ParameterTypeRequiredDescription
reasoning_effortstringOptional"low" | "medium" | "high". OpenAI o1/o3, modelli di reasoning GPT-5 e qualsiasi router che li mappi.
thinkingstring | objectOptional"on" | "off" | "auto" per un’attivazione rapida, oppure { type: "enabled", budget_tokens: N } per la forma nativa di Anthropic. Si associa al thinking esteso di Claude, al thinking di Gemini e al reasoning di DeepSeek.
thinking_budgetintegerOptionalNumero massimo di token che il modello può spendere nel ragionamento prima di emettere un output visibile. Specchia budget_tokens.

Sforzo di ragionamento (stile 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"
  }'

Pensiero esteso (stile 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 traccia stessa del ragionamento appare in choices[0].message.reasoning (forma OpenAI) o come thinking blocchi dentro content (Formato Anthropic). I gettoni ragionamento vengono fatturati e riportati usage.completion_tokens_details.reasoning_tokens.

Quel dettaglio completion_tokens_details.reasoning_tokens è presente solo quando il provider upstream lo riporta. In una risposta in stream la traccia arriva su delta.reasoning_content per ogni chunk.


Input di visione e immagine

Modelli con supports_vision: true accettare immagini incorporate come blocchi di contenuto. Funziona sia un URL pubblico che un URL di dati base64; i limiti di dimensione dipendono dal modello a monte.

Modelli con supporto visivo

· 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"}}
      ]
    }]
  }'

Chiamata dello strumento

Modelli con supports_tools: true può chiamare le funzioni definite dall'utente. Il modello restituisce a tool_calls vettore; esegui la chiamata, quindi invii il risultato in a tool messaggio.

Modelli con supporto per la chiamata degli strumenti

· live

Richiesta

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"
  }'

Risposta con chiamata utensile

{
  "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"
  }]
}

Follow-up con il risultato dello strumento

{
  "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.


Streaming

Impostato stream: true per ricevere completamenti parziali come eventi inviati dal server. Ogni evento è un blocco JSON con la stessa forma della risposta non trasmessa in streaming, tranne message è sostituito da delta. Lo streaming 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 filo

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 di messaggistica compatibile con Anthropic. Funziona con il funzionario @anthropic-ai/sdk impostando baseURL A https://api.airforce. Inoltra a OpenAI/Google/ecc. in modo trasparente per i modelli non Claude.

POSThttps://api.airforce/v1/messages

Richiedi corpo

ParameterTypeRequiredDescription
modelstringRequiredID modello (formato Anthropic o alias instradato).
messagesarrayRequiredOgni voce: { role: "user" | "assistant", content: string | array }.
max_tokensintegerRequiredRichiesto da Anthropic. Limite token per la risposta.
systemstring | arrayOptionalPrompt di sistema. Passa un array di blocchi { type: "text", text, cache_control? } per contrassegnare i segmenti di prefisso memorizzati nella cache. Vedi "Prompt caching".
temperaturefloatOptional0–1.
top_pfloatOptionalCampionamento del nucleo.
top_kintegerOptionalLimita il pool di campionamento ai token top-K.
stop_sequencesarrayOptionalFino a 4 sequenze di arresto.
streambooleanOptionalQuando è vero, emette un flusso di eventi SSE in stile Anthropic (vedi "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.
toolsarrayOptionalDefinizioni degli strumenti Anthropic: { name, description, input_schema }. La risposta può contenere blocchi di contenuto tool_use.
tool_choiceobjectOptional{ type: "auto" | "any" | "tool", name? }.
thinkingobjectOptionalPensiero esteso Anthropic: { type: "enabled", budget_tokens: N }.

Esempio

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 della risposta

ParameterTypeRequiredDescription
idstringOptionalID del messaggio, ad es. "msg_01ABCxyz".
typestringOptionalSempre "messaggio".
rolestringOptionalSempre "assistente".
contentarrayOptionalArray di blocchi di contenuto: { type: "text" | "tool_use" | "thinking", … }.
modelstringOptionalEco del modello richiesto.
stop_reasonstringOptional"fine_turno" | "max_token" | "stop_sequenza" | "strumento_uso".
usageobjectOptional{ input_tokens, output_tokens, cache_read_input_tokens?, cache_creation_input_tokens?, cache_creation? }. I campi cache compaiono quando è stato usato il prompt caching. cache_creation.ephemeral_5m_input_tokens e ephemeral_1h_input_tokens forniscono la suddivisione delle scritture per TTL.

Eventi in streaming

Anthropic SSE utilizza eventi denominati anziché blocchi JSON una tantum. Ogni evento ha sia un event: nome e a data: Carico utile 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.


Memorizzazione nella cache immediata

SU /v1/messages con i modelli Claude, contrassegna un prefisso come memorizzato nella cache passando system come un array di blocchi in cui trasporta il segmento memorizzato nella cache cache_control: { type: "ephemeral" }. Le richieste successive che iniziano con lo stesso prefisso addebitano la tariffa di lettura della cache più economica. Modelli con supports_caching: true In /v1/models sostenere questo.

Modelli con memorizzazione nella cache immediata

· 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?"}
  ]
}

Come vengono riportati i conteggi cache nella risposta

I conteggi dei token cache vengono passati nella forma nativa di ogni formato, così gli SDK (openai, @anthropic-ai/sdk, @google/genai) li leggono senza codice personalizzato. I campi vengono omessi quando il valore è zero, mantenendo leggere le risposte non cached.

/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
}

Dove si applica la cache

I marcatori cache_control espliciti sono rispettati su /v1/messages e /v1/chat/completions per i modelli Claude — mettili sui blocchi di contenuto system o message. Molti altri provider (famiglia OpenAI, DeepSeek, Gemini) mettono in cache automaticamente: non invii marcatori e vedi semplicemente cached_tokens nella risposta quando un prefisso abbastanza lungo viene riutilizzato.

Durata della cache: 5 minuti o 1 ora

Un prefisso in cache vive 5 minuti per impostazione predefinita e il timer si rinnova a ogni hit. Per un prefisso più duraturo, aggiungi ttl: "1h" al marcatore. La risposta riporta ogni TTL separatamente sotto cache_creation.

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

Esempio: prima write, poi read

Invia esattamente la stessa richiesta due volte (l’esempio di cache sopra). La prima chiamata che vede il prefisso paga una write di cache una tantum; le chiamate identiche entro la TTL pagano la read di cache molto più economica.

Prima chiamata — write di cache (estratto usage):

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

Seconda chiamata identica entro la TTL — read di cache:

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

Limiti e costo

  • Claude richiede un prefisso minimo memorizzabile (circa 1024 token; di più per alcuni modelli). I prefissi più corti semplicemente non vengono messi in cache.
  • Fino a 4 breakpoint di cache per richiesta, e il prefisso in cache deve essere identico byte per byte tra le chiamate — anche una modifica di un carattere manca la cache.
  • Le write di cache costano più dell’input normale (5m ≈ 1,25×, 1h ≈ 2×); le read costano molto meno (≈ 0,1×). Vedi i prezzi di cache di ogni modello nella pagina prezzi.

POST /v1/responses

Superficie OpenAI Responses-API per conversazioni stateful. Stessa autenticazione Bearer/x-api-key. I conteggi cache compaiono come input_tokens_details.cached_tokens (lettura) più cache_creation_input_tokens flat + cache_creation.ephemeral_* (scritture) per parità 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.


Errori

Airforce restituisce codici di stato HTTP standard e una busta di errore uniforme per entrambi gli endpoint.

ParameterTypeRequiredDescription
400invalid_request_errorOptionalJSON non valido, campo obbligatorio mancante, modello sconosciuto.
401invalid_request_error / auth_requiredOptionalChiave API mancante o non valida.
402insufficient_quotaOptionalIl modello richiede un abbonamento attivo o un saldo Pay-as-you-Go positivo.
403model_access_denied / insufficient_scopeOptionalLe autorizzazioni per piano o per chiave negano questa richiesta.
404model_not_foundOptionalIl modello richiesto non esiste o non hai accesso ad esso.
429rate_limit_errorOptionalLa tariffa della richiesta o il limite massimo di token giornaliero è stato superato.
503api_error / moderation_unavailableOptionalTutte le chiavi upstream per il provider richiesto non sono riuscite.
{
  "error": {
    "message": "The requested model does not exist or you do not have access to it.",
    "type": "model_not_found",
    "param": null,
    "code": "404"
  }
}

Lo slug descrittivo si trova in type. code è lo stato HTTP come stringa (es. "404"), e param è null tranne che negli errori di validazione del range dei parametri, dove indica il parametro problematico.

Scopri i modelli

Consulta l'elenco completo degli ID modello e i relativi flag di capacità (visione, strumenti, ragionamento, memorizzazione nella cache, lunghezza del contesto, ...) all'indirizzo /docs/api/models.

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