Ir al contenido

API REST

Los agentes de Sherlock se exponen con una API compatible con la de OpenAI (/v1/chat/completions). Cualquier SDK o herramienta que hable con OpenAI funciona cambiando la dirección base y usando el slug del agente como modelo.

https://app.sherlock.posselab.net/v1

Cada llamada pasa por el mismo motor que el resto de los canales: guardrails, búsqueda en el conocimiento, herramientas, trazas, costos y presupuesto.

Mandá la API key en el encabezado Authorization:

Authorization: Bearer sk-sherlock-...

También se acepta X-API-Key: sk-sherlock-.... Hay dos tipos de key:

Key Dónde se crea Alcance
Del workspace Configuración → API keys Todos los agentes del workspace (elegís el agente con model) o uno solo.
De un canal API Estudio → Canales → API Un solo agente.

El ambiente lo define la key: una key de «Producción» usa la versión publicada de cada agente; una de «Borrador», el borrador actual. Agregar @draft al modelo no cambia el ambiente.

POST /v1/chat/completions

En los ejemplos, API_KEY es una variable de entorno con tu key.

Ventana de terminal
curl https://app.sherlock.posselab.net/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "asistente-seguros",
"messages": [{"role": "user", "content": "¿Qué cubre la póliza de auto contra todo riesgo?"}]
}'
Campo Tipo Notas
model string Slug del agente (o su ID). Obligatorio con keys de workspace; se ignora con keys de un solo agente. El slug figura en la lista de la API key («Nombre (slug)») y en GET /v1/models.
messages array Mensajes en formato OpenAI. Sherlock responde al último mensaje del usuario.
stream boolean true para recibir la respuesta en streaming (SSE). Por defecto false.
conversation_id string Para continuar una conversación (ver abajo). También se puede mandar en el encabezado X-Sherlock-Conversation.
user string Identificador de la persona en tu sistema. Aparece en Conversaciones. No mandes datos personales acá: usá un ID interno.

Otros campos de OpenAI (temperature, max_tokens…) se aceptan y se ignoran: el comportamiento lo define la configuración del agente.

{
"id": "chatcmpl-3f9a1c0e8b7d4a2e9c6b5d10",
"object": "chat.completion",
"created": 1759680000,
"model": "asistente-seguros",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "La póliza contra todo riesgo cubre los daños propios del vehículo… [1]"
},
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 1830, "completion_tokens": 142, "total_tokens": 1972 },
"sherlock": {
"conversation_id": "8d2f5b1e-6a1c-4f0e-9b7a-2c3d4e5f6a7b",
"run_id": "c41e9a77-0b2d-4c8e-a1f3-5d6e7f809a1b",
"status": "ok",
"citations": [
{
"n": 1,
"document_id": "…",
"document": "Condiciones generales auto.pdf",
"url": null,
"page": 12,
"heading": "Cláusula 4 · Cobertura todo riesgo",
"snippet": "El Asegurador indemnizará los daños materiales…",
"score": 0.83
}
],
"cost_usd": 0.00041,
"version": 3,
"handoff": false
}
}

El campo sherlock agrega lo que la API de OpenAI no tiene:

Campo Qué es
conversation_id La conversación en Sherlock. Mandalo en el próximo mensaje para continuarla.
run_id La ejecución: es el identificador de la traza en Conversaciones.
status ok, blocked (un guardrail frenó el mensaje; content trae la respuesta configurada), handoff (la conversación está derivada a una persona), budget_exceeded (se agotó el presupuesto) o error.
citations Las fuentes citadas: número (el [1] del texto), documento, página, sección, fragmento y puntaje.
cost_usd Costo de la respuesta en modelos.
version Versión del agente que respondió (en borrador, null).
handoff true si la conversación quedó derivada a una persona.

Con los SDK de OpenAI, sherlock llega como un campo adicional de la respuesta. Por ejemplo, con el SDK de Node.js:

import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://app.sherlock.posselab.net/v1", apiKey: process.env.API_KEY });
const r = await client.chat.completions.create({
model: "asistente-seguros",
messages: [{ role: "user", content: "¿Cómo denuncio un siniestro?" }],
});
console.log(r.choices[0].message.content);
console.log(r.sherlock.citations);

Para que el agente recuerde el contexto, mandá el conversation_id que devolvió la primera respuesta:

Ventana de terminal
curl https://app.sherlock.posselab.net/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "X-Sherlock-Conversation: 8d2f5b1e-6a1c-4f0e-9b7a-2c3d4e5f6a7b" \
-d '{"model": "asistente-seguros", "messages": [{"role": "user", "content": "¿Y si el auto es 0 km?"}]}'
  • Si mandás conversation_id y un solo mensaje, Sherlock usa el historial que tiene guardado. Es lo más simple: no hace falta reenviar la conversación.
  • Si mandás varios mensajes, usa el historial que mandaste.
  • Sin conversation_id, cada llamada empieza una conversación nueva.

El agente recuerda tantos intercambios como indique su «Memoria (turnos de historial)».

Con "stream": true, la respuesta llega como Server-Sent Events con el formato estándar de OpenAI:

Ventana de terminal
curl -N https://app.sherlock.posselab.net/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "asistente-seguros", "stream": true, "messages": [{"role": "user", "content": "¿Qué es la franquicia?"}]}'
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"La franquicia es el monto que "},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{…},"sherlock":{"conversation_id":"…","run_id":"…","status":"ok","citations":[…],"version":3}}
data: [DONE]

El texto llega por frases (Sherlock revisa cada tramo con la salida segura antes de enviarlo). El último fragmento trae usage y sherlock con la conversación y las citas.

Con el mismo SDK:

import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://app.sherlock.posselab.net/v1", apiKey: process.env.API_KEY });
const stream = await client.chat.completions.create({
model: "asistente-seguros",
stream: true,
messages: [{ role: "user", content: "¿Qué documentación necesito para un reintegro?" }],
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");

GET /v1/models devuelve los agentes a los que puede hablar la key (uno, si la key es de un solo agente):

Ventana de terminal
curl https://app.sherlock.posselab.net/v1/models -H "Authorization: Bearer $API_KEY"
{
"object": "list",
"data": [
{ "id": "asistente-seguros", "object": "model", "created": 1759600000, "owned_by": "sherlock", "name": "Asistente de seguros" }
]
}

Los errores tienen el formato {"detail": "…"}:

Código Mensaje Qué hacer
400 «Indicá el agente en el campo ‘model’ (slug o id)» Con keys de workspace, mandá model.
401 «Falta la API key (Authorization: Bearer sk-sherlock-…)» Agregá el encabezado.
401 «API key inválida o revocada» Revisá la key o creá una nueva.
404 «Agente no encontrado para esta API key» El slug no existe en el workspace de la key, o el agente está archivado.
409 «El agente todavía no tiene una versión publicada en producción.» Publicá el agente o usá una key de «Borrador».
422 «Dato inválido en …» El cuerpo no tiene el formato esperado (por ejemplo, falta messages).
429 «Demasiadas solicitudes. Probá de nuevo en un minuto.» Superaste el límite por minuto de la key. Reintentá con espera.

Algunas situaciones responden 200 con un status especial, porque el agente sí contestó:

  • blocked: un guardrail frenó el mensaje (prompt injection, tema bloqueado, mensaje demasiado largo). content trae la respuesta configurada.
  • budget_exceeded: el workspace llegó a su presupuesto con la acción «Pausar los agentes». content trae «El servicio alcanzó su límite de uso mensual. Contactá al administrador.»
  • handoff: la conversación está derivada a una persona y el agente no responde (content vacío). Las respuestas del operador quedan en el historial de la conversación en Sherlock.
  • Pedidos por minuto: los de cada key (60 por defecto en las del workspace, configurable hasta 10.000; 600 en las de un canal API). Al superarlo, 429.
  • Largo del mensaje: el que defina el guardrail del agente (4.000 caracteres por defecto).
  • Presupuesto: el del workspace.

Como la API es compatible con OpenAI, también funciona con herramientas de evaluación como Promptfoo. La vista Evaluación de cada agente exporta su configuración lista: ver Exportar a Promptfoo.