Documentación

Referencia de la API

La autenticación, la superficie de endpoints compatible con OpenAI, el streaming, el razonamiento y la taxonomía de errores.

Autenticación

Cada petición a /v1/* se autentica con una clave virtual en la cabecera Authorization: Bearer. Acuñe claves en la Consola; el secreto se muestra una sola vez y solo se almacena su hash. Una clave lleva sus propios límites de tasa, presupuesto, etiquetas, una lista opcional de modelos permitidos (vacía = cualquier modelo) y option_overrides dispersos que se desvían de la política de la organización (modo de protección de datos, modelo NER, modo del análisis de inyecciones).

Una petición cuyo modelo no está en la lista de permitidos no vacía de la clave se rechaza con un 403 permission_error sellado antes de despachar nada; el propio rechazo queda registrado en la cadena de auditoría.

Acuñar una clave de producción requiere una dirección de correo verificada.

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 expone la superficie compatible con OpenAI que se muestra a continuación. Los endpoints sin un handler de primera clase se retransmiten literalmente al proveedor enrutado, streaming incluido, de modo que los upstreams compatibles con OpenAI conservan plena fidelidad.

EndpointPropósito
POST /v1/chat/completionsChat completions, la superficie principal: enrutamiento, protección de datos, caché, streaming.
POST /v1/completionsText completions heredadas.
POST /v1/embeddingsEmbeddings; también alimenta la caché semántica.
POST /v1/moderationsClasificación de moderación.
POST /v1/responsesLa API de Responses de OpenAI.
POST /v1/ocrOCR de documentos (Mistral, o totalmente local con el modelo sluis/ocr) · facturado por página. Con la política dlp_documents activa, los documentos inline se anonimizan antes de salir.
POST /v1/documents/anonymizeAnonimización de documentos · los PII se convierten en «MERGE_TAG»s, las imágenes se difuminan · facturado por página/imagen.
POST /v1/documents/anonymize/jobsTrabajos de anonimización asíncronos · encole documentos grandes, consulte el estado y recoja el resultado con una URL firmada de duración limitada sin clave de API.
GET /v1/modelsLos modelos que su política y sus credenciales pueden alcanzar de verdad, nada hipotético.
GET /v1/models/{id}Metadatos de un modelo.
POST /v1/audio/*Transcripción, traducción, voz · retransmitido al proveedor enrutado.
POST /v1/images/*Generación y edición de imágenes · retransmitido.
POST /v1/video/generationsGeneración de vídeo · retransmitido.
/v1/filesOperaciones con archivos · retransmitido.
POST /v1/messagesEntrada nativa Anthropic Messages · apunte cualquier herramienta con SDK de Anthropic a Sluis; cualquier modelo conectado.
POST /v1/messages/count_tokensEstimación local de tokens para la gestión de contexto del SDK de Anthropic; no se envía nada.
POST /v1beta/models/{model}:generateContentEntrada nativa de Google Gemini · apunte un SDK de Gemini a Sluis (:streamGenerateContent transmite).
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 }'

Documentos como entrada

Adjunte un PDF, un documento Word, una imagen o un archivo de texto a una petición de chat como parte de contenido "type": "file" con una URL file_data en base64. Cualquier modelo enrutado lo acepta: los proveedores que entienden partes de archivo de forma nativa las reciben sin cambios, y para todos los demás la pasarela convierte el documento antes del envío. Las referencias file_id del proveedor no se resuelven; incluya los bytes como file_data.

Los modelos con visión reciben cada página del PDF renderizada como parte image_url (presupuesto de 48 páginas por petición, compartido entre todos los documentos adjuntos); los modelos sin entrada de imagen reciben el texto extraíble del documento insertado como texto del prompt, que el escaneo de protección de datos cubre después como cualquier otro texto. Los documentos más largos o pesados corresponden a /v1/ocr. Con la política dlp_documents activada, el documento se anonimiza o se rechaza antes de que nada salga de la pasarela. Si está desactivada y el modo DLP de la organización es protector (tokenize, mask o block), los documentos que viajarían como imágenes no inspeccionables se rechazan; con allow_log pasan con un marcador explícito de no analizado en el registro de auditoría.

# 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

Ponga stream: true y la respuesta llega como server-sent events: cada frame es un delta chat.completion.chunk y el stream termina con data: [DONE]. Los streams nunca se almacenan en búfer en la pasarela: pasan a través de ella en modo tee, y el sellado de auditoría y la medición ocurren aunque el cliente cuelgue antes de tiempo.

Pida stream_options.include_usage y el frame final lleva el uso exacto de tokens, las mismas cifras que la pasarela mide y factura.

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

Razonamiento

Pase el parámetro OpenAI reasoning_effort (minimal | low | medium | high) en cualquier modelo con capacidad de razonamiento. Sluis lo traduce por proveedor (el nivel de pensamiento de Gemini, el esfuerzo de pensamiento adaptativo de Claude) y lo omite donde un modelo lo rechazaría, así que un solo parámetro funciona en todo el catálogo.

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
)

Códigos de error

Los errores usan el sobre de error de OpenAI; el valor error.type refleja el estado HTTP, así que el manejo de errores de su SDK sigue funcionando sin cambios.

CódigoCuándo
400 invalid_request_errorCuerpo de la petición o parámetros mal formados.
400 invalid_request_errorIdentificador de modelo sin prefijo de proveedor. Cada identificador invocable es provider/model, p. ej. mistral/mistral-large-latest; el cuerpo indica: model must be provider-prefixed.
400 invalid_request_errorLa petición lleva la cabecera x-sluis-dlp, ya eliminada. Las anulaciones por petición fueron sustituidas por los option overrides por clave; configúrelos en Consola → API keys.
401 authentication_errorClave de API ausente o desconocida.
402 insufficient_quotaSin plan activo o presupuesto alcanzado. Active un plan o suba el presupuesto; la petición nunca llega a un proveedor.
403 permission_errorLa clave carece de permiso, por ejemplo el modelo no está en su lista de permitidos.
422 invalid_request_errorRechazada antes de despachar, por ejemplo la protección de datos en modo block coincidió con la petición.
422 document_too_large_to_scanUna página del documento supera el tope de píxeles de renderizado incluso a la resolución mínima de escaneo. Las páginas de gran formato (planos A0/A1) se renderizan reducidas automáticamente; el código dedicado permite al cliente reducir la página y reenviarla.
429 rate_limit_errorLímite de tasa alcanzado. Se aplica en la pasarela; la petición nunca llega a un proveedor.
451 permission_errorBloqueada por la política de residencia: ninguna jurisdicción permitida sirve la petición. El cuerpo incluye el motivo.
5xx api_errorFallo del proveedor upstream tras los reintentos; el cortacircuitos desvía el tráfico de los proveedores no saludables.
{
  "error": {
    "message": "model must be provider-prefixed, e.g. mistral/mistral-large-latest",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_request"
  }
}