siati.ai docs

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.

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

bash
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ù.