Ga naar de inhoud

API-referentie

Authenticatie, endpoints, streaming, reasoning en fouten op het OpenAI-oppervlak, de native Anthropic-API's en de compatibiliteitsmatrix per endpoint.

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 wordt bewaard. Een key is een credential voor een workload. De workload beheert rate limits, budget, toegestane modellen en beleidsafwijkingen; verzoeken blijven ook onder het organisatiebeleid vallen.

Een verzoek waarvan het model niet op de niet-lege allow-list van de workload 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.

Workload-inloggegevens: beheer API-keys en hun toegangsinstellingen.
Workload-inloggegevens: beheer API-keys en hun toegangsinstellingen.Engelstalige interface · illustratieve demogegevens. Open de afbeelding op volledig formaat.
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, plus de native Anthropic-paden die verderop in detail staan. Endpoints zonder een eigen handler worden letterlijk doorgestuurd naar de gerouteerde provider, streaming inbegrepen, zodat OpenAI-compatibele upstreams volledige getrouwheid behouden. Een browser die een pad opent dat de API niet bedient, zoals de kale API-host, wordt doorgestuurd naar deze docs; API-clients krijgen nog steeds een gewone 404.

EndpointDoel
POST /v1/chat/completionsChat completions, het primaire oppervlak: routing, gegevensbescherming, caching, streaming.
POST /v1/completionsLegacy text completions.
POST /v1/embeddingsEmbeddings.
POST /v1/moderationsModeratieclassificatie.
POST /v1/responsesDe OpenAI Responses API.
POST /v1/systemoneNative System One typed decisions, not OpenAI chat messages.
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. mistral/image-generation is de uitzondering: Mistral biedt beeldgeneratie alleen via zijn agent-connector, dus de gateway vertaalt de OpenAI-request en antwoordt met b64_json, gefactureerd per beeld.
POST /v1/video/generationsVideogeneratie · doorgestuurd.
/v1/filesBestandsbewerkingen · doorgestuurd met de eigen key van je organisatie (BYOK of eigen provider), nooit met beheerde keys.
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.
GET /anthropic/v1/modelsNative Anthropic-modeldiscovery · list en get in de Anthropic-vorm, uit de in-process catalogus. Op /v1/models kiest de anthropic-version-header dezelfde vorm.
HEAD /api/helloWarmloop-probe voor Anthropic-SDK-clients zoals Claude Code · 200 met een leeg body.
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" }] }'
Playground met een gekozen model en een afgerond voorbeeldverzoek.
Playground met een gekozen model en een afgerond voorbeeldverzoek.Engelstalige interface · illustratieve demogegevens. Open de afbeelding op volledig formaat.

Elke JSON-body hierboven mag daarnaast de gateway-extensie sluis.remove dragen, die termen noemt die vóór verzending uit de prompt gepseudonimiseerd moeten worden. Ze wordt verwijderd voordat het verzoek de gateway verlaat; zie de Gegevensbeschermingsreferentie.

# 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"], "remove": ["Project Nightingale"], "include_mapping": true }'
Playground Documents: upload een document om te anonimiseren.
Playground Documents: upload een document om te anonimiseren.Engelstalige interface · illustratieve demogegevens. Open de afbeelding op volledig formaat.

System One typed decisions

# The router behind sluis/auto: send state only, not questions.
curl https://api.sluis.ai/v1/systemone \
  -H "Authorization: Bearer $SLUIS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"sluis/typed/router",
       "state":{"request":"Compare these two supplier contracts clause by clause and list the risks.",
                "previous":"Here are both contracts.",
                "attachments":["contract_a.pdf (application/pdf)","contract_b.pdf (application/pdf)"]}}'
Local-pack contractBehaviour
Model idssluis/typed answers your own questions on a local open model (GLiNER2.5-Decide). sluis/typed/router is the router Sluis uses for sluis/auto, with its own calibrated questions.
sluis/typed/routerSend the text a request carries: state.request (required), and optional previous, system and attachments (a string or a list of "name (mime)" strings); a plain string is the request. It answers reasoning (noul, P(needs multi-step reasoning)), complexity (score, 0 trivial to 3 hard, with legend and probabilities per level) and task (choice over code, writing, translation, extraction, document, support, smalltalk, action). decision holds the route and demand sluis/auto would take from this text alone, or null. Files, images, JSON mode, tools, prompt size and your organisation's policy are not part of this input and can change a real sluis/auto route. answers.reasoning keeps the keys it always had; the rest is additional.
Plain sluis/typedAlways answered on Sluis infrastructure, never by an outside provider. When the local model is unavailable the call returns 503. GET /v1/models lists it only when it can answer.
TypeSafeBring your own key only; no sluis/* alias reaches it. Name the model explicitly, for example typesafe/jev-latest. The normal gate applies: it is a US provider, so your residency policy must allow US.
AvailabilityEvery answer comes from verified model weights, reported as revision. If the local model is unavailable or cannot be verified, the call fails closed with 503.
StateRequired JSON object, list (array) or string, at most 128 KiB (131072 bytes) of serialized JSON before DLP. Missing or invalid state returns 422; oversized state returns 413. The open pack reads the first 384 words.
Questionssluis/typed/router supplies its own calibrated questions: any questions field, including null or an empty object, returns 400. Plain sluis/typed requires 1 to 16 questions of type noul, choice (2 to 20 options) or score (2 to 20 levels), each with instructions; missing questions return 422, a malformed set 400, more than 64 KiB 413. The characters [ ] ( ) and backticks are removed before the model reads them, so options that then collide return 400, as does a set longer than about 1,000 tokens.
ResponseJSON with model, answers and revision (weights SHA256); sluis/typed/router adds decision. Each answer has its type, its typed value (choice, score or noul), confidence and, where the pack reports them, probabilities, legend and answer_confidence. On sluis/typed gate on answer_confidence; its probabilities are uncalibrated. No chat completion or streaming envelope.
Latencysluis/typed/router usually answers well under 200 ms; when busy it returns 503 with Retry-After: 2. Plain sluis/typed runs all questions in one CPU pass: about 2 s for a prompt-sized state, up to about 7 s for a long one, with a 10 s budget.
Data protectionTenant DLP applies locally to the state and to the questions' instructions and criteria: block refuses; tokenize or mask rewrites what the pack is shown. Per-request removal terms are honoured.
ResidencyProcessed on Sluis infrastructure with no outside provider and no upstream residency routing step.
MeteringEach successful local decision is sealed and billed per input token at €0.01 per 1M tokens; output is free. The pack reports no token count, so input is estimated at about 4 characters per token over the state and questions it was shown. Normal limits, budgets and model allow-lists still apply.
AliasesAn existing tenant alias with the same name takes precedence over the local pack.

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.

Na 15 seconden zonder frame schrijft de gateway tussen events een SSE-commentaarregel (: keepalive), zodat proxy's met een idle-timeout de verbinding openhouden terwijl een model nadenkt; SSE-clients negeren die. Streams dragen Cache-Control: no-cache en X-Accel-Buffering: no. Wanneer een gateway-replica herstart, bedient die open streams nog tot vijf minuten; een stream die daarna nog open is, eindigt met een error-event met code server_restarting, dus probeer het verzoek opnieuw.

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
)

Prompt-caching

Terugkerende promptprefixen — een lange systeemprompt, tooldefinities, een groeiend gesprek — kunnen bij de provider gecacht worden: goedkoper en sneller. Sluis spreekt de standaardmarkers van de industrie: cache_control-blokken in Anthropic-stijl (met een optionele TTL van 5m of 1h) en OpenAI's top-level prompt_cache_key. Stuur ze in één vorm; Sluis vertaalt of verwijdert ze per provider, zodat hetzelfde verzoek over de hele catalogus werkt.

ProviderGedrag prompt-cache
AnthropicExpliciete cache_control-breekpunten op systeemblokken, berichtinhoud en tooldefinities, met een TTL van 5m of 1h. Cache-reads en cache-writes worden apart gerapporteerd.
Bedrockcache_control wordt vertaald naar Converse cachePoint-blokken in system, messages en toolConfig — hetzelfde verzoek, niets te herschrijven aan jouw kant.
OpenAI · AzureAutomatische caching op lange prefixen. Markers worden verwijderd; een optionele prompt_cache_key gaat ongewijzigd mee zodat vervolgaanroepen cache-affiniteit houden.
Gemini · VertexBij Gemini-modellen cachet de provider impliciet — niets te sturen, en het gerapporteerde aandeel gecachte tokens gaat door naar je verbruik. Claude op Vertex neemt expliciete cache_control, TTL en al, precies zoals bij Anthropic.
xAI · DeepSeek · Mistral · Qwen · Moonshot · ZhipuAutomatisch waar de provider het aanbiedt. Expliciete markers worden weggefilterd, dus een verzoek dat voor Claude is geschreven wordt hier nooit geweigerd.
Scaleway · customScaleway heeft geen prompt-cache bij de provider: directives worden daar weggefilterd en de hendel is de optionele responscache van de gateway. Een eigen endpoint krijgt beide directives ongewijzigd — dat gedrag is het contract van de operator.

Expliciete prompt-caching is opt-in op organisatieniveau en staat standaard uit: een gecachte prefix is data at rest bij de provider — eerst door de DLP van Sluis gefilterd, maar buiten Sluis bewaard voor de cache-TTL. Zet het aan in de weergave Gegevensbescherming van de Console. Sommige providers (OpenAI, Gemini, xAI, DeepSeek) cachen toch al automatisch in hun eigen infrastructuur; de schakelaar bepaalt alleen wat Sluis expliciet doorstuurt (cache_control, cachePoint, prompt_cache_key), niet het interne gedrag van de provider. Zonder eigen sleutel voor een provider lopen aanroepen via een Sluis-credential die andere organisaties delen: bij OpenAI en Azure zet Sluis een uit je organisatie afgeleide prompt_cache_key in plaats van de jouwe, en bij alle andere providers tonen de gecachte-tokentellers in je verbruik 0. De afrekening past nog steeds de echte cachekorting toe.

Cache-reads worden afgerekend tegen het verlaagde providertarief; cache-writes in Anthropic-stijl leggen de write-opslag van de provider op het inputtarief. Beide zijn per aanroep zichtbaar in de audit-drawer en opgeteld in Gebruik & budget. Met een door Sluis beheerde key wordt een verzoek dat een toeslag kiest die Sluis niet kan meten — een cache_control-ttl anders dan 5m waar de provider die honoreert (Anthropic, Bedrock, Claude op Vertex), een service_tier anders dan auto, default, flex of standard_only, of de long-context-bèta van Anthropic (context-1m) — geweigerd met 400 voordat er iets wordt verstuurd; je eigen provider-key stuurt alle drie ongewijzigd door.

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 workload; stel ze in via Console → Workloads.
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 document is te groot voor de route die het nam: een pagina die zelfs op de minimale scanresolutie boven het pixelplafond van de rendering blijft, of een bestand boven de bytelimiet van tekstextractie. Grootformaatpagina's (A0/A1-tekeningen) worden automatisch gedownscaled gerenderd; de eigen code laat een client het document verkleinen of splitsen en opnieuw aanbieden.
429 rate_limit_errorRate limit bereikt. Afgedwongen op de gateway; het verzoek bereikt nooit een provider.
403 permission_errorGeblokkeerd door het residency-beleid: geen toegestane jurisdictie bedient het verzoek. De body bevat de reden.
403 scope_violationGeweigerd door de scopebewaking van de workload in modus block: de call valt buiten de scope die voor die workload is geschreven. Het bericht bevat de reden van de bewaking en het verzoek bereikt nooit een provider.
503 pdf_renderer_unavailableEen inline PDF moest als paginabeelden worden verstuurd omdat het gerouteerde model beeldinvoer leest, maar deze deployment heeft geen PDF-renderer. Het verzoek wordt geweigerd in plaats van stilzwijgend beantwoord op basis van geëxtraheerde tekst, wat alles zou weggooien wat een tekening of scan toont.
503 scope_guard_unavailableDe scopebewaking van de workload staat op block maar kwam niet tot een oordeel, dus de call wordt geweigerd in plaats van doorgelaten. Probeer opnieuw met backoff.
503 auth_unavailableBramka nie mogła odczytać magazynu kluczy, więc nie mogła zweryfikować klucza. Klucz nie jest uznany za nieprawidłowy; ponów z rosnącym odstępem i uwzględnij Retry-After.
504 api_errorDe provider antwoordde niet binnen de antwoordtermijn van de workload: 300 seconden tenzij de workload 10 tot 600 instelt, korter als het verzoek x-sluis-upstream-timeout meestuurde. error.sluis.cause is timeout. De gateway heeft de call niet opnieuw verstuurd omdat de provider er nog mee bezig kan zijn; kort de prompt in of vraag een langere termijn voordat je opnieuw verstuurt.
5xx api_errorUpstream-providerfout na retries; de circuit breaker leidt verkeer om onhealthy providers heen. De body bevat het bericht van de provider zelf plus een error.sluis-object dat de oorzaak noemt en elke poging, met de upstream-status of transportfout en de duur.
{
  "error": {
    "message": "model must be provider-prefixed, e.g. mistral/mistral-large-latest",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_request"
  }
}

Anthropic Messages API

Sluis spreekt de Anthropic Messages API native. Richt Claude Code of een willekeurige Anthropic-SDK op de gateway en roep POST /v1/messages aan: het verzoek wordt naar de interne vorm vertaald, doorloopt precies dezelfde Inspect → Route → Seal → Meter-pijplijn als elke andere aanroep en wordt terugvertaald naar de Anthropic-vorm, streaming inbegrepen. /anthropic/v1/messages is het ondubbelzinnige pad met prefix naar dezelfde handler.

Authenticatie

Stuur je Sluis-key mee in de x-api-key-header van Anthropic of in de gebruikelijke Authorization: Bearer-header; beide worden geaccepteerd. De anthropic-version-header wordt gelezen maar nooit vereist, en alleen de vorm ervan wordt gevalideerd. Het parsen is bewust open: onbekende bodyvelden, onbekende contentbloktypen, onbekende anthropic-beta-waarden en de query ?beta=true die Claude Code meestuurt worden getolereerd in plaats van geweigerd. Beta-flags gaan byte voor byte mee naar upstreams uit de Anthropic-familie en worden elders genegeerd.

Endpoints

EndpointDoel
POST /v1/messagesMessages, gebufferd of streamend · systeemprompts als string of blokken, tools en tool-resultaten (ook foutresultaten en afbeeldingsblokken daarin), afbeeldingen, documentblokken, thinking- en redacted_thinking-blokken uit de historie, en cache_control-markers op elke cachebare positie.
POST /v1/messages/count_tokensLokale tokenschatting voor contextbeheer in de SDK: er wordt niets verzonden, bewaard of gemeterd.
GET /v1/models · GET /v1/models/{id}Native modeldiscovery in de Anthropic-vorm (data, has_more, first_id, last_id, display_name, created_at, best-effort before_id/after_id/limit-cursors), geantwoord uit de in-process catalogus zonder databasegang. Op het rootpad kiest de anthropic-version-header deze vorm — zonder die header krijg je de OpenAI-vorm; onder /anthropic geldt hij altijd. Id's blijven de door Sluis aanroepbare provider/model-id's en created_at is een vaste placeholder, want de catalogus kent geen releasedatum per model.
HEAD /api/helloDe warmloop-probe die Claude Code vóór een sessie stuurt · alleen HEAD, geantwoord met 200 en een leeg body.

Modelroutering

Het wire-formaat beperkt het model nooit: de ingang is een codec en het model-id bepaalt de route. Een kaal id zoals claude-sonnet-5 lost op via de standaardprovider van deze ingang — anthropic tenzij je organisatie hem elders richt, bijvoorbeeld vertex voor Claude in de EU — waarna de residency-poort nog altijd beslist of dat doel het verzoek mag bedienen. Pin een doel expliciet met een provider-geprefixt id (vertex/claude-opus-4-8) of geef een sluis/*-alias mee: een Anthropic-SDK-tool loopt dan op elke aangesloten provider, binnen je beleid.

Streaming

Met "stream": true is het antwoord de volledige Anthropic-eventgrammatica: message_start met het echte aantal inputtokens, content_block_start / content_block_delta / content_block_stop per blok, message_delta met cumulatief gebruik inclusief cache-read- en cache-creation-tokens, en dan message_stop. Tekst komt als text_delta, tool-argumenten als input_json_delta en reasoning als thinking_delta plus signature_delta wanneer de gerouteerde provider die heeft geproduceerd. Een ping-event volgt op message_start en herhaalt zich na ongeveer 15 seconden stilte upstream, zodat een lang nadenkende beurt nooit een client-watchdog laat afgaan, en een fout halverwege de stream wordt heruitgegeven als een error-event in plaats van een afgekapte stream. stop_sequence draagt de gematchte reeks wanneer het antwoord van een provider uit de Anthropic-familie kwam en is anders null.

# native Anthropic Messages — the model id owns the route, not the wire format
curl https://api.sluis.ai/v1/messages \
  -H "x-api-key: $SLUIS_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{ "model": "vertex/claude-opus-4-8",
        "max_tokens": 256,
        "system": "Be concise.",
        "messages": [{ "role": "user", "content": "Say hi" }] }'

# /anthropic/v1/messages is the unambiguous prefixed path for the same handler

Fouten

Elke fout op deze paden gebruikt de envelop van Anthropic — een "type": "error" op het hoogste niveau met het foutentype van de leverancier (invalid_request_error, authentication_error, billing_error, permission_error, not_found_error, conflict_error, request_too_large, rate_limit_error, api_error, overloaded_error) — inclusief de weigeringen die nooit een model bereiken, zoals een onbekende key of een blokkade door gegevensbescherming. Het request-id van de gateway staat als request-id-header op de respons en als request_id-veld in het body, en dat is hetzelfde id waarmee de aanroep in het auditspoor terugkomt.

# every failure on /v1/messages* is Anthropic-shaped — auth and
# data-protection refusals included, never an OpenAI envelope
{
  "type": "error",
  "error": {
    "type": "rate_limit_error",
    "message": "rate limit exceeded"
  },
  "request_id": "req_9f2e…"
}

Eén requestveld wordt geweigerd in plaats van doorgestuurd: mcp_servers geeft 400 invalid_request_error. Een model dat zelf een externe MCP-server aanroept zou buiten de Sluis-poort vallen, dus registreer de server in de Console en gebruik de MCP-gateway op /v1/mcp, waar elke tool-aanroep wordt geïnspecteerd, gerouteerd, verzegeld en gemeterd.

Compatibiliteitsmatrix

Wat de native ingangen vandaag dekken, endpoint voor endpoint. Deze tabel ís de claim: wat hier niet als ondersteund staat, is roadmap, wordt bewust geweigerd of is een ander productoppervlak — nooit stilzwijgend gesuggereerd.

AnthropicStatusToelichting
POST /v1/messages✓ nativeGebufferd en streamend, tools, afbeeldingen, documentblokken, thinking-retour en prompt-cachemarkers.
POST /v1/messages/count_tokens✓ lokale schattingLokaal geantwoord; er wordt niets verzonden.
GET /v1/models · /v1/models/{id}✓ nativeNative list- en get-vorm uit de in-process catalogus; op het rootpad via header-onderhandeling, onder /anthropic altijd.
HEAD /api/hello✓De warmloop-probe van Claude Code, alleen HEAD.
Message Batches✗ roadmapMessage Batches zijn niet geïmplementeerd; batchwerk loopt vandaag als gewone live aanroepen.
Files✗ roadmapDe Files API is niet doorgeschakeld; inline documentblokken en file_data dekken het gangbare pad.
mcp_servers✗ geweigerdGeweigerd met 400 in plaats van doorgestuurd — registreer de server en roep de Sluis MCP-gateway op /v1/mcp aan.
Skills · Agents · Admin✗ buiten scopeSkills, managed agents en de admin-, gebruiks- en kosten-API's zijn een ander productoppervlak, geen inferentiecompatibiliteit.

Routering tussen protocollen. Leverancierseigen velden blijven bewaard zolang het verzoek landt bij een provider die hetzelfde protocol spreekt: een Anthropic-verzoek dat door een provider uit de Anthropic-familie wordt bediend houdt zijn thinking-blokken, cachemarkers, beta-flags en gematchte stop_sequence. Gaat hetzelfde verzoek naar een ander protocol, dan vallen die velden bij verzending weg — nooit een weigering bij de ingang — en de auditregel legt zowel het wire-formaat als de gekozen provider vast, zodat elk verlies toewijsbaar is. Ondoorzichtige waarden worden nooit herschreven: thinking-signatures en redacted_thinking-payloads gaan letterlijk mee of helemaal niet, en daarom wordt een geparkeerd thinking-blok dat de gegevensbeschermingsscan markeert weggelaten in plaats van gemaskeerd — een herschreven blok zou een ongeldige signature dragen.