API reference
Ogni parametro: onorato o rifiutato
L'elenco completo di cosa accettiamo su /v1/chat/completions, cosa arriva al motore e cosa rifiutiamo con un 400. Nessun parametro viene accettato e ignorato.
Last updated: 2026-08-18
Ogni parametro: onorato o rifiutato
Su questa interfaccia un parametro può finire in due modi, e non ce n'è un terzo:
- arriva al motore e fa quello che dice il suo nome;
- viene rifiutato con un 400 che lo nomina e dice cosa usare invece.
Non esiste il caso «accettato e ignorato», ed è la regola più utile di questa pagina: se la richiesta torna 200, quello che avete scritto è stato applicato.
Perché lo scriviamo così esplicitamente
Perché fino al 18 agosto 2026 non era vero. Il gateway accettava sette
parametri e li buttava senza dirlo: max_completion_tokens, stop, n,
seed, logprobs, top_logprobs, parallel_tool_calls. Ne accettava anche
un ottavo, top_p, che era perfino nella tabella di questa documentazione.
La risposta arrivava 200 e sembrava giusta.
Il caso peggiore era n. Il gateway lo inoltrava, il motore generava le
risposte richieste e le fatturava tutte, e noi restituivamo la prima
buttando le altre: si pagavano token che non si vedevano mai. Peggio che
ignorare il parametro.
Il caso più costoso era max_completion_tokens, che è il nome nuovo con cui
OpenAI raccomanda di scrivere il tetto ai token. Chi lo usava non aveva alcun
tetto, e lo scopriva a consuntivo.
Segnalato dal team che sviluppa un gestionale svizzero sopra questa interfaccia, con la frase che ha deciso come è fatta la correzione: «un errore si scopre in sviluppo, un tetto ignorato si scopre a consuntivo».
Onorati
Provati sul motore uno per uno il 18 agosto 2026, e poi dal gateway pubblico.
| parametro | cosa fa | note |
|---|---|---|
model |
quale modello | vedi il catalogo |
messages |
la conversazione | ruoli system, user, assistant, tool |
temperature |
0–2 | più basso, più prevedibile |
top_p |
0–1 | campionamento a nucleo |
max_tokens |
tetto ai token generati | fino a 8192 |
max_completion_tokens |
lo stesso tetto, nome nuovo | usate questo |
stop |
dove fermarsi | stringa o elenco; la stringa la convertiamo noi |
n |
quante risposte | 1–8; le paghi tutte, e ora le vedi tutte |
seed |
ripetibilità | a parità di tutto il resto, stessa risposta |
presence_penalty |
−2…2 | |
frequency_penalty |
−2…2 | |
logit_bias |
bias per token | mappa id token → −100…100 |
logprobs |
probabilità dei token | compaiono in choices[].logprobs |
top_logprobs |
0–20 alternative per token | richiede logprobs: true |
parallel_tool_calls |
più chiamate insieme, sì o no | con false ne arriva una per volta |
tools / tool_choice |
chiamata di funzioni | vedi JSON e funzioni |
response_format |
forma della risposta | anche con stream: true |
stream / stream_options |
risposta a pezzi | vedi streaming |
user |
un vostro riferimento | vedi sotto |
service_tier |
auto o default |
abbiamo un solo livello; per la velocità usate X-Siati-Tier |
Il tetto ai token, e i due nomi
max_tokens e max_completion_tokens sono lo stesso tetto. Se ne mandate uno,
vale quello. Se ne mandate due con lo stesso numero, va bene. Se ne mandate due
con numeri diversi, rispondiamo 400: due tetti diversi nella stessa
richiesta vogliono dire che chi l'ha scritta crede in uno dei due, e indovinare
quale è il modo di far pagare al cliente la nostra supposizione.
user, e dove finisce
Il campo user finisce nel dettaglio dei vostri consumi, accanto a ogni
richiesta. Serve a voi per separare i vostri utenti, i vostri reparti o i
vostri clienti dentro una fattura sola. È una stringa che ci date e che vi
restituiamo tale e quale: non la colleghiamo a niente e non la usiamo per
altro.
Se cercate un header X-Siati-User, non c'è più: era documentato e non era mai
stato implementato. Usate user, che è il nome di OpenAI e funziona con le
librerie che avete già.
logprobs e n non li fanno tutti i modelli
Li fanno i modelli serviti da vLLM — oggi gemma-4-26b e
apertus-70b-instruct. Sugli altri arriva un 400 che nomina il parametro e
dice su quali modelli funziona, non un 502 e non un silenzio.
Rifiutati, con il motivo
| parametro | perché |
|---|---|
metadata |
non conserviamo le conversazioni: non c'è niente a cui attaccare delle etichette. Usate user. |
store |
non conserviamo le conversazioni. È una scelta, non una funzione mancante. |
functions |
forma superata: usate tools. |
function_call |
forma superata: usate tool_choice. |
modalities, audio |
per la voce ci sono gli endpoint dedicati. |
prediction |
il motore non lo fa. |
web_search_options |
i nostri modelli non escono su internet, per costruzione. |
Qualunque altro parametro
Un nome che non riconosciamo dà 400 e viene nominato. Comprende i refusi, che
è la parte più utile: tempreature prima passava, la temperatura restava
quella per difetto e non c'era modo di accorgersene dalla risposta.
{
"error": {
"message": "Parametri non riconosciuti: «tempreature». Li rifiutiamo invece di ignorarli, perché un parametro accettato e scartato non si vede dalla risposta. Accettiamo: …",
"type": "invalid_request_error",
"param": "tempreature"
}
}
Trascrizione: timestamp_granularities
Vale la stessa regola. timestamp_granularities: ["word"] restituisce i tempi
per parola in words, con inizio, fine e probabilità di ognuna. Fino al 18
agosto il campo veniva accettato e non inoltrato, quindi tornavano i soli
segmenti.
I tempi esistono solo dentro response_format: "verbose_json": nelle altre due
forme non c'è un posto dove metterli, e chiederli senza verbose_json dà 400
invece di una risposta senza tempi, che non si distingue da un audio in cui le
parole non si sentivano.
curl https://api.siati.ai/v1/audio/transcriptions \
-H "Authorization: Bearer $SIATI_API_KEY" \
-F file=@nota.wav \
-F model=whisper-1 \
-F response_format=verbose_json \
-F "timestamp_granularities[]=word"
Come facciamo a non ripetere l'errore
La causa non era la distrazione di qualcuno: era che la validazione della richiesta restituiva solo i campi elencati, e tutto il resto sparisce senza un errore e senza una riga di registro. Un difetto così non si trova rileggendo il codice, perché non c'è niente da vedere.
Adesso l'elenco dei parametri sta in un posto solo, e un collaudo automatico fallisce se un campo viene validato senza finire né al motore né fra i rifiutati. L'abbiamo verificato aggiungendo di proposito un parametro dimenticato: il collaudo lo ha nominato.
Non ci difende dal non sostenere qualcosa che vi serve. Ci difende dal sostenerlo per finta, che è la cosa che vi costa di più.