Documentatie

API-referentie

Authenticatie, het OpenAI-compatibele endpoint-oppervlak, streaming, reasoning en de fouttaxonomie.

Authenticatie

Elk verzoek naar /v1/* authenticeert met een virtuele key in de Authorization: Bearer-header. Keys maak je aan in de Console; het secret wordt één keer getoond en alleen de hash ervan wordt bewaard. Een key draagt zijn eigen rate limits, budget, tags, een optionele allow-list voor modellen (leeg = elk model) en spaarzame option_overrides die afwijken van het organisatiebeleid (gegevensbeschermingsmodus, NER-model, injectiescanmodus).

Een verzoek waarvan het model niet op de niet-lege allow-list van de key staat, wordt geweigerd met een verzegelde 403 permission_error voordat er iets wordt verzonden; de weigering zelf belandt in de auditketen.

Het aanmaken van een productie-key vereist een geverifieerd e-mailadres.

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

Endpoints

Sluis biedt het onderstaande OpenAI-compatibele oppervlak. Endpoints zonder een eigen handler worden letterlijk doorgestuurd naar de gerouteerde provider, streaming inbegrepen, zodat OpenAI-compatibele upstreams volledige getrouwheid behouden.

EndpointDoel
POST /v1/chat/completionsChat completions, het primaire oppervlak: routing, gegevensbescherming, caching, streaming.
POST /v1/completionsLegacy text completions.
POST /v1/embeddingsEmbeddings; voeden ook de semantische cache.
POST /v1/moderationsModeratieclassificatie.
POST /v1/responsesDe OpenAI Responses API.
POST /v1/ocrDocument-OCR (Mistral, of volledig lokaal met model sluis/ocr) · gefactureerd per pagina. Met het dlp_documents-beleid aan worden inline documenten geanonimiseerd voor vertrek.
POST /v1/documents/anonymizeDocumentanonimisering · PII wordt vervangen door «MERGE_TAG»s, afbeeldingen worden vervaagd · gefactureerd per pagina/afbeelding.
POST /v1/documents/anonymize/jobsAsynchrone anonimiseringsjobs · zet grote documenten in de wachtrij, volg de status en haal het resultaat op via een tijdgebonden ondertekende URL zonder API-sleutel.
GET /v1/modelsDe modellen die je beleid en credentials daadwerkelijk kunnen bereiken, niets hypothetisch.
GET /v1/models/{id}Metadata van één model.
POST /v1/audio/*Transcriptie, vertaling, spraak · doorgestuurd naar de gerouteerde provider.
POST /v1/images/*Beeldgeneratie en -bewerkingen · doorgestuurd.
POST /v1/video/generationsVideogeneratie · doorgestuurd.
/v1/filesBestandsbewerkingen · doorgestuurd.
POST /v1/messagesNative Anthropic Messages-ingang · richt elke Anthropic-SDK-tool op Sluis; elk verbonden model.
POST /v1/messages/count_tokensLokale tokenschatting voor Anthropic-SDK-contextbeheer; er wordt niets verzonden.
POST /v1beta/models/{model}:generateContentNative Google Gemini-ingang · richt een Gemini-SDK op Sluis (:streamGenerateContent streamt).
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 }'

Documenten als invoer

Voeg een PDF, Word-document, afbeelding of tekstbestand aan een chat-request toe als content-part "type": "file" met een base64 file_data data-URL. Elk gerouteerd model accepteert dit: providers die file-parts native begrijpen krijgen ze ongewijzigd, en voor alle andere converteert de gateway het document vóór verzending. File_id-referenties aan providerzijde worden niet opgelost; neem de bytes op als file_data.

Modellen met vision krijgen elke PDF-pagina gerenderd als image_url-part (budget van 48 pagina's per request, gedeeld over alle bijgevoegde documenten); modellen zonder beeldinvoer krijgen de extraheerbare tekst van het document als prompttekst, die de databeschermingsscan daarna dekt zoals elke andere tekst. Langere of zwaardere documenten horen op /v1/ocr. Met de dlp_documents-policy aan wordt het document geanonimiseerd of geweigerd voordat er iets de gateway verlaat. Staat die uit en is de DLP-modus van de organisatie beschermend (tokenize, mask of block), dan worden documenten die als niet-inspecteerbare afbeeldingen zouden reizen geweigerd; onder allow_log passeren ze met een expliciete niet-gescand-markering in het auditlog.

# 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

Zet stream: true en het antwoord komt binnen als server-sent events: elk frame is een chat.completion.chunk-delta en de stream eindigt met data: [DONE]. Streams worden nooit gebufferd in de gateway: ze lopen er via een tee doorheen, en de auditverzegeling en metering gebeuren zelfs als de client vroegtijdig ophangt.

Vraag om stream_options.include_usage en het laatste frame draagt het exacte tokengebruik, dezelfde cijfers die de gateway meet en factureert.

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="")

Redeneren

Geef de OpenAI-parameter reasoning_effort (minimal | low | medium | high) door op elk model dat kan denken. Sluis vertaalt hem per provider (het denkniveau van Gemini, de adaptieve denk-inspanning van Claude) en laat hem weg waar een model hem zou weigeren, zodat één parameter over de hele catalogus werkt.

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
)

Foutcodes

Fouten gebruiken de OpenAI-foutenvelop; de waarde error.type weerspiegelt de HTTP-status, zodat de foutafhandeling van je SDK ongewijzigd blijft werken.

CodeWanneer
400 invalid_request_errorOnjuiste request-body of parameters.
400 invalid_request_errorModel-id zonder providerprefix. Elk aanroepbaar id is provider/model, bijv. mistral/mistral-large-latest; de body meldt: model must be provider-prefixed.
400 invalid_request_errorHet verzoek draagt de verwijderde x-sluis-dlp header. Overrides per verzoek zijn vervangen door option overrides per key; stel ze in via Console → API keys.
401 authentication_errorOntbrekende of onbekende API-key.
402 insufficient_quotaGeen actief plan of budget bereikt. Activeer een plan of verhoog het budget; het verzoek bereikt nooit een provider.
403 permission_errorDe key mist toestemming, bijvoorbeeld het model staat niet op de allow-list.
422 invalid_request_errorGeweigerd vóór verzending, bijvoorbeeld gegevensbescherming in block-modus matchte het verzoek.
422 document_too_large_to_scanEen documentpagina blijft zelfs op de minimale scanresolutie boven het pixelplafond van de rendering. Grootformaatpagina's (A0/A1-tekeningen) worden automatisch gedownscaled gerenderd; de eigen code laat een client de pagina verkleinen en opnieuw aanbieden.
429 rate_limit_errorRate limit bereikt. Afgedwongen op de gateway; het verzoek bereikt nooit een provider.
451 permission_errorGeblokkeerd door het residency-beleid: geen toegestane jurisdictie bedient het verzoek. De body bevat de reden.
5xx api_errorUpstream-providerfout na retries; de circuit breaker leidt verkeer om onhealthy providers heen.
{
  "error": {
    "message": "model must be provider-prefixed, e.g. mistral/mistral-large-latest",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_request"
  }
}