Documentazione

Riferimento API

L'autenticazione, la superficie di endpoint compatibile OpenAI, lo streaming, il reasoning e la tassonomia degli errori.

Autenticazione

Ogni richiesta a /v1/* si autentica con una chiave virtuale nell'header Authorization: Bearer. Genera le chiavi nella Console; il segreto viene mostrato una sola volta e ne viene memorizzato solo l'hash. Una chiave porta i propri rate limit, budget, tag, una lista opzionale di modelli consentiti (vuota = qualsiasi modello) e option_overrides sparsi che deviano dalla policy dell'organizzazione (modalità di protezione dei dati, modello NER, modalità della scansione injection).

Una richiesta il cui modello non è nella lista di consentiti non vuota della chiave viene rifiutata con un 403 permission_error sigillato prima che venga inoltrato alcunché; il rifiuto stesso finisce nella catena di audit.

Generare una chiave di produzione richiede un indirizzo email verificato.

curl https://api.sluis.ai/v1/models \
  -H "Authorization: Bearer $SLUIS_KEY"

# a model outside the key's allow-list never dispatches:
# → 403 permission_error · the refusal is sealed in the audit chain

Endpoint

Sluis espone la superficie compatibile OpenAI qui sotto. Gli endpoint senza un handler di prima classe vengono inoltrati alla lettera al provider instradato, streaming incluso, così gli upstream compatibili OpenAI mantengono piena fedeltà.

EndpointScopo
POST /v1/chat/completionsChat completions, la superficie principale: instradamento, protezione dei dati, caching, streaming.
POST /v1/completionsText completions legacy.
POST /v1/embeddingsEmbeddings; alimenta anche la cache semantica.
POST /v1/moderationsClassificazione di moderazione.
POST /v1/responsesL'API Responses di OpenAI.
POST /v1/ocrOCR di documenti (Mistral, o completamente locale con il modello sluis/ocr) · fatturato a pagina. Con la policy dlp_documents attiva, i documenti inline vengono anonimizzati prima di uscire.
POST /v1/documents/anonymizeAnonimizzazione di documenti · i PII diventano «MERGE_TAG», le immagini vengono sfocate · fatturato per pagina/immagine.
POST /v1/documents/anonymize/jobsJob di anonimizzazione asincroni · accoda documenti grandi, controlla lo stato e scarica il risultato con un URL firmato a tempo senza chiave API.
GET /v1/modelsI modelli che la tua policy e le tue credenziali possono davvero raggiungere, niente di ipotetico.
GET /v1/models/{id}I metadati di un modello.
POST /v1/audio/*Trascrizione, traduzione, voce · inoltrato al provider instradato.
POST /v1/images/*Generazione e modifica di immagini · inoltrato.
POST /v1/video/generationsGenerazione di video · inoltrato.
/v1/filesOperazioni sui file · inoltrato.
POST /v1/messagesIngresso nativo Anthropic Messages · punta qualsiasi tool con SDK Anthropic verso Sluis; qualsiasi modello connesso.
POST /v1/messages/count_tokensStima locale dei token per la gestione del contesto dell'SDK Anthropic; non viene inviato nulla.
POST /v1beta/models/{model}:generateContentIngresso nativo Google Gemini · punta un SDK Gemini verso Sluis (:streamGenerateContent trasmette in streaming).
curl https://api.sluis.ai/v1/chat/completions \
  -H "Authorization: Bearer $SLUIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "mistral/mistral-large-latest",
        "messages": [{ "role": "user", "content": "Say hi" }] }'
# Document OCR, billed per page. Returns pages[] markdown + usage_info.pages_processed.
# model "sluis/ocr" runs the gateway's own OCR engine: fully local, no provider egress (inline data: URLs only).
curl https://api.sluis.ai/v1/ocr \
  -H "Authorization: Bearer $SLUIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "mistral/mistral-ocr-latest", "document": { "type": "document_url", "document_url": "https://example.com/invoice.pdf" } }'
# Document anonymization, billed per page/image. PII becomes «MERGE_TAG»s; images are blurred.
curl https://api.sluis.ai/v1/documents/anonymize \
  -H "Authorization: Bearer $SLUIS_KEY" \
  -F file=@contract.docx \
  -F 'options={ "entities": ["person_name", "email", "iban"], "include_mapping": true }'

Documenti in input

Allega un PDF, un documento Word, un'immagine o un file di testo a una richiesta chat come parte di contenuto "type": "file" con una URL file_data in base64. Qualsiasi modello instradato la accetta: i provider che capiscono nativamente le parti file le ricevono invariate, e per tutti gli altri il gateway converte il documento prima dell'invio. I riferimenti file_id lato provider non vengono risolti; includi i byte come file_data.

I modelli con visione ricevono ogni pagina del PDF renderizzata come parte image_url (budget di 48 pagine per richiesta, condiviso tra tutti i documenti allegati); i modelli senza input immagine ricevono il testo estraibile del documento inserito come testo del prompt, che la scansione di protezione dei dati copre poi come ogni altro testo. I documenti più lunghi o pesanti vanno su /v1/ocr. Con la policy dlp_documents attiva, il documento viene anonimizzato o rifiutato prima che qualcosa lasci il gateway. Se è disattivata e la modalità DLP dell'organizzazione è protettiva (tokenize, mask o block), i documenti che viaggerebbero come immagini non ispezionabili vengono rifiutati; con allow_log passano con un marcatore esplicito di non analizzato nel registro di audit.

# Attach a document as an OpenAI-style `file` content part. The gateway
# normalizes it for the routed provider, so this works on any model.
curl https://api.sluis.ai/v1/chat/completions \
  -H "Authorization: Bearer $SLUIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "scaleway/gemma-4-26b-a4b-it",
        "messages": [{ "role": "user", "content": [
          { "type": "file",
            "file": { "filename": "drawing.pdf",
                      "file_data": "data:application/pdf;base64,'"$(base64 -w0 drawing.pdf)"'" } },
          { "type": "text", "text": "Which discipline does this drawing document?" }
        ] }] }'

Streaming

Imposta stream: true e la risposta arriva come server-sent events: ogni frame è un delta chat.completion.chunk e lo stream termina con data: [DONE]. Gli stream non vengono mai bufferizzati nel gateway: lo attraversano in tee, e il sigillo di audit e la misurazione avvengono anche se il client si disconnette in anticipo.

Richiedi stream_options.include_usage e il frame finale porta l'uso esatto dei token, gli stessi numeri che il gateway misura e fattura.

stream = client.chat.completions.create(
    model="mistral/mistral-large-latest",
    messages=[{"role": "user", "content": "Write a haiku"}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

Ragionamento

Passa il parametro OpenAI reasoning_effort (minimal | low | medium | high) su qualsiasi modello capace di ragionamento. Sluis lo traduce per provider (il thinking level di Gemini, l'adaptive thinking effort di Claude) e lo omette dove un modello lo rifiuterebbe, così un solo parametro funziona su tutto il catalogo.

resp = client.chat.completions.create(
    model="vertex/claude-opus-4-8",
    messages=[{"role": "user", "content": "Prove it step by step…"}],
    reasoning_effort="high",  # minimal | low | medium | high
)

Codici di errore

Gli errori usano l'envelope di errore di OpenAI; il valore error.type rispecchia lo stato HTTP, così la gestione degli errori del tuo SDK continua a funzionare invariata.

CodiceQuando
400 invalid_request_errorCorpo della richiesta o parametri malformati.
400 invalid_request_errorId del modello senza prefisso del provider. Ogni id richiamabile è provider/model, ad es. mistral/mistral-large-latest; il body riporta: model must be provider-prefixed.
400 invalid_request_errorLa richiesta porta l'header x-sluis-dlp, rimosso. Le deroghe per richiesta sono state sostituite dagli option overrides per chiave; configurali in Console → API keys.
401 authentication_errorChiave API mancante o sconosciuta.
402 insufficient_quotaNessun piano attivo o budget raggiunto. Attiva un piano o alza il budget; la richiesta non raggiunge mai un provider.
403 permission_errorLa chiave non ha il permesso, ad esempio il modello non è nella sua lista di consentiti.
422 invalid_request_errorRifiutata prima dell'inoltro, ad esempio la protezione dei dati in modalità block ha trovato corrispondenza nella richiesta.
422 document_too_large_to_scanUna pagina del documento supera il tetto di pixel di rendering anche alla risoluzione minima di scansione. Le pagine di grande formato (disegni A0/A1) vengono renderizzate ridotte automaticamente; il codice dedicato consente al client di ridurre la pagina e reinviarla.
429 rate_limit_errorRate limit raggiunto. Applicato al gateway; la richiesta non raggiunge mai un provider.
451 permission_errorBloccata dalla policy di residenza: nessuna giurisdizione consentita serve la richiesta. Il body include il motivo.
5xx api_errorErrore del provider upstream dopo i retry; il circuit breaker devia il traffico attorno ai provider non integri.
{
  "error": {
    "message": "model must be provider-prefixed, e.g. mistral/mistral-large-latest",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_request"
  }
}