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 y una lista opcional de modelos permitidos (vacía = cualquier modelo).

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 }'

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.
401 authentication_errorClave de API ausente o desconocida.
402 insufficient_quotaAsignación gratuita agotada 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.
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"
  }
}