Guías
Agente de IA
El agente de IA de heysteff les responde a tus clientes en WhatsApp, Instagram, Messenger, SMS y correo con tus instrucciones, tus archivos de contexto y tus custom tools, y le pasa la conversación a tu equipo cuando corresponde. Viene en los tres planes developer: pagas los tokens a tu proveedor con tu propia key, o usas el cupo de prueba del plan.
Deja el agente apagado y sigue Conecta tu propia IA. Un espacio developer nace con el agente apagado, así no responde encima de tu modelo. Las dos formas usan la misma bandeja, los mismos canales y los mismos webhooks.
Cómo funciona#
- Un cliente escribe por cualquier canal conectado.
- Si el agente está encendido para ese canal y esa conversación, lee el historial, tus instrucciones y tus archivos de contexto. Si hace falta, llama a tus custom tools.
- Responde por el mismo canal y te avisa con
agent.replied. Si no debe seguir, pasa la conversación a tu equipo, pausa el bot y te avisa conagent.handoff. - Tu equipo sigue desde la bandeja, en la web o en la app móvil, con todo el historial.
Encender y apagar#
Hay cuatro niveles. El del espacio es el interruptor general: apagado ahí, el agente no responde en ningún canal.
| Nivel | Cómo | Detalle |
|---|---|---|
| Espacio | PATCH /v1/agent con "enabled": true, o la consola → Agente. | Un espacio nuevo nace apagado. |
| Canal | "channels": [{ "id": "<channel_connection_id>", "enabled": false }] | true lo enciende, false lo apaga y null vuelve a heredar. |
| Cliente de tu SaaS | "customers": [{ "id": "<customer_id>", "enabled": false }] | Vale para todos los canales que conectó ese cliente. Un canal con su propio valor manda sobre el de su cliente. |
| Conversación | POST /v1/conversations/{id}/bot con { "paused": true } o { "paused": false }. | Pausa o reanuda el bot solo en esa conversación. /escalate también lo pausa y /resolve lo reactiva. |
curl -X PATCH https://app.heysteff.com/api/v1/agent \
-H "Authorization: Bearer $HEYSTEFF_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"provider": "anthropic",
"model": "claude-haiku-5-5",
"temperature": 0.3,
"channels": [{ "id": "8a1f0c2e-5d3b-4c6a-9e7f-0a1b2c3d4e5f", "enabled": false }],
"customers": [{ "id": "6f1c2a8e-3b4d-4e5f-9a0b-1c2d3e4f5a6b", "enabled": null }]
}'GET /v1/agent devuelve el estado completo: encendido, instrucciones, proveedor, modelo, temperatura, keys guardadas (solo sus últimos 4), el cupo de prueba del mes, cada canal y cliente con su agent_enabled y los modelos sugeridos con su precio. Todos los campos del PATCH son opcionales, pero manda al menos uno.
Instrucciones y base de conocimiento#
instructionses el prompt del agente, hasta 10.000 caracteres: quién es, qué tono usa, qué puede prometer y cuándo debe pasarle la conversación a una persona.temperatureva de 0 (preciso) a 1 (creativo).- Archivos de contexto: lo que el agente consulta para responder, como precios, políticas, horarios o preguntas frecuentes. Por ahora se administran desde el servidor MCP (
list_context_files,upsert_context_file,patch_context_file,delete_context_file) o pidiéndoselo al asistente de la consola; no tienen endpoint en la API v1.
Modelos y precios#
provider puede ser anthropic, openai, deepseek u openrouter, y model es el id del modelo en ese proveedor. La lista de abajo es una sugerencia, no un catálogo cerrado: con OpenRouter puedes usar cualquier vendor/model. Si no eliges proveedor ni modelo, el agente usa el modelo por defecto de la plataforma.
| Proveedor | Modelo | Entrada, por millón de tokens | Salida, por millón de tokens |
|---|---|---|---|
| Anthropic | claude-haiku-5-5 | USD 0,10 | USD 0,50 |
| Anthropic | claude-sonnet-5-5 | USD 2,00 | USD 10,00 |
| Anthropic | claude-opus-5-5 | USD 4,00 | USD 20,00 |
| OpenAI | gpt-4o-mini | USD 0,15 | USD 0,60 |
| OpenAI | gpt-4o | USD 2,50 | USD 10,00 |
| DeepSeek | deepseek-v4-flash | USD 0,30 | USD 1,20 |
| DeepSeek | deepseek-v4-pro | USD 1,32 | USD 3,96 |
| OpenRouter | anthropic/claude-haiku-5-5 | USD 0,10 | USD 0,50 |
| OpenRouter | openai/gpt-4o-mini | USD 0,15 | USD 0,60 |
Son precios de lista de referencia, los mismos que devuelve GET /v1/agent en models. Con tu key, lo que vale es la tarifa de tu proveedor, que te cobra directo.
Quién paga: tu key o el cupo de prueba#
Con tu key (BYOK). Guarda la key de tu proveedor con PUT /v1/agent/keys o en la consola → Agente. Queda cifrada y nunca vuelve por la API: GET /v1/agent muestra solo el proveedor y sus últimos 4. Hay una key por proveedor; el agente usa la del proveedor que elegiste en provider. DELETE /v1/agent/keys/{provider} la borra. Tu proveedor te cobra los tokens y heysteff no les suma nada.
curl -X PUT https://app.heysteff.com/api/v1/agent/keys \
-H "Authorization: Bearer $HEYSTEFF_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "provider": "anthropic", "api_key": "sk-ant-..." }'Sin key. Cada respuesta descuenta del cupo de prueba del mes calendario (UTC), con la key de heysteff. El asistente de la consola usa el mismo cupo. Lo ves en GET /v1/agent → quota (period, used, limit, remaining).
| Plan | Respuestas de prueba al mes | Custom tools | Hallazgos |
|---|---|---|---|
| Developer Free | 200 | 2 | No incluido |
| Developer | 2.000 | 10 | Incluido |
| Developer Platform | 20.000 | Ilimitadas | Incluido |
Sin key y sin cupo, el agente no responde. Nunca cambia a otro proveedor por su cuenta. A tu webhook llega agent.failed con code: "ai_quota_exhausted" y el mensaje del cliente queda en la bandeja para tu equipo. Vuelve a responder cuando guardas tu key, cuando empieza el mes siguiente o cuando subes de plan. Ver Precios.
Errores#
| Dónde | Código | Qué pasó |
|---|---|---|
Webhook agent.failed | ai_quota_exhausted | Sin key propia y sin cupo de prueba este mes. Trae quota. |
Webhook agent.failed | provider_error | Tu proveedor falló: key inválida, caída o límite de su lado. Trae provider, model, status_code y credential. |
| Asistente de la consola | 402 ai_quota_exhausted | El mismo caso: sin key y sin cupo. Viene con fix y details. |
/v1/agent | 403 developer_workspace_only | La key es de un espacio de heysteff que no es developer. |
PATCH /v1/agent | 404 channel_not_found, customer_not_found | Un canal o cliente de la lista no existe en tu espacio. |
POST /v1/agent/tools | 402 plan_limit | Llegaste al cupo de custom tools de tu plan (details.resource = "custom_tools"). |
{
"error": {
"code": "ai_quota_exhausted",
"message": "...",
"fix": "...",
"details": { "period": "2026-11", "used": 200, "limit": 200 }
}
}Custom tools#
Una custom tool es una llamada HTTP a tu backend que el agente hace en plena conversación: ver el estado de un pedido, consultar stock o reservar una hora. El agente decide cuándo usarla leyendo su description, y completa los argumentos que declaras en spec.parameters_schema. Cada {{args.x}} de url_template, query_template, headers o body_template tiene que estar declarado ahí.
curl -X POST https://app.heysteff.com/api/v1/agent/tools \
-H "Authorization: Bearer $HEYSTEFF_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "estado_pedido",
"name": "Estado de un pedido",
"description": "Busca el estado de un pedido por su número. Úsala cuando el cliente pregunte dónde está su compra.",
"spec": {
"method": "GET",
"url_template": "https://api.tu-empresa.com/pedidos/{{args.numero}}",
"parameters_schema": {
"type": "object",
"properties": { "numero": { "type": "string", "description": "Número del pedido" } },
"required": ["numero"]
},
"timeout_ms": 8000
}
}'GET /v1/agent/toolsyGET /v1/agent/tools/{id}las listan y muestran (sin secretos).PATCH /v1/agent/tools/{id}las edita;specse reemplaza completa, así que manda la spec entera con tu cambio."is_active": falsela desactiva sin borrarla.DELETE /v1/agent/tools/{id}la borra.- La credencial hacia tu backend (por ejemplo, un token bearer) se carga en la consola: por la API no viajan secretos de terceros.
Webhooks del agente#
Llegan solo a los espacios developer, con el mismo sobre y la misma firma que el resto de los webhooks. Suscríbete a ellos al crear el webhook.
| Evento | Cuándo | Campos de data |
|---|---|---|
agent.replied | El agente respondió. Con el modo copiloto, mode es suggestion y la respuesta espera aprobación en la bandeja. | conversation_id, trigger_message_id, message_ids, mode, text, channel_type, channel_connection_id, provider, model, credential (byok o platform) |
agent.handoff | El agente le pasó la conversación a una persona. | conversation_id, escalation_id, reason, by, bot_paused |
agent.failed | El agente no pudo responder. | conversation_id, trigger_message_id, code, message, provider, y según el caso quota o model, status_code y credential |
insight.detected | El análisis semanal de tus conversaciones encontró algo que revisar. | report_id, funnel_id, week_start, week_end, unresolved, knowledge_gaps, top_gaps |
{
"event": "agent.replied",
"data": {
"conversation_id": "c0a8012e-...",
"trigger_message_id": "5b7e...",
"message_ids": ["9f2c..."],
"mode": "sent",
"text": "...",
"channel_type": "whatsapp_cloud",
"channel_connection_id": "8a1f0c2e-...",
"provider": "anthropic",
"model": "claude-haiku-5-5",
"credential": "byok"
}
}{
"event": "agent.failed",
"data": {
"conversation_id": "c0a8012e-...",
"trigger_message_id": "5b7e...",
"code": "ai_quota_exhausted",
"message": "...",
"provider": "anthropic",
"quota": { "period": "2026-11", "used": 200, "limit": 200, "remaining": 0 }
}
}Hallazgos#
En Developer y Developer Platform, heysteff analiza tus conversaciones y te muestra tres listas: clientes frustrados (frustrated), lo que el agente no supo responder o respondió mal (agent_gaps) y conversaciones sin resolver (unresolved). Cada lista trae total e items.
- En la consola, en la sección Hallazgos.
- Con
GET /v1/insights?days=30&limit=10(scopeinsights:read):daysva de 1 a 90 ylimitde 1 a 50. En Developer Free respondeincluded: false. - Con el webhook
insight.detected, una vez por semana cuando el análisis encuentra algo.
Usa los hallazgos para mejorar las instrucciones y los archivos de contexto: lo que aparece en agent_gaps suele ser una respuesta que falta en la base de conocimiento.
Asistente de la consola#
En la consola hay un asistente lateral al que le preguntas por tu espacio en lenguaje natural: por qué falló un webhook, qué pasó en una conversación, cuánto cupo te queda. También ejecuta acciones con las mismas tools del servidor MCP, y antes de cualquier cambio o envío a una persona te muestra lo que va a hacer y espera tu confirmación.
Usa la key del proveedor del agente si la guardaste; si no, el mismo cupo de prueba. Sin ninguna de las dos responde 402 ai_quota_exhausted.
Desde tu IA (MCP) y el SDK#
get_developer_agentyupdate_developer_agent: ver y configurar el agente, con los mismos campos quePATCH /v1/agent.delete_developer_ai_key: borra la key de un proveedor. La key no se guarda por MCP porque es un secreto: guárdala en la consola o conPUT /v1/agent/keys.get_developer_insights: los hallazgos.list_custom_tools,create_custom_tool,update_custom_toolydelete_custom_tool: las custom tools.set_conversation_bot: pausa o reanuda el bot en una conversación.
Con el SDK de TypeScript:
import { Heysteff } from '@heysteff/sdk';
const heysteff = new Heysteff(); // lee HEYSTEFF_API_KEY
await heysteff.agent.setKey({ provider: 'anthropic', api_key: process.env.ANTHROPIC_API_KEY! });
const agent = await heysteff.agent.update({ enabled: true, model: 'claude-haiku-5-5' });
console.log(agent.quota, agent.keys); // keys: solo proveedor y últimos 4
const tools = await heysteff.agent.tools.list();
const insights = await heysteff.insights.get({ days: 7 });
console.log(insights.agent_gaps.total);La referencia completa de cada endpoint, con sus campos, está en la referencia de la API, en la sección Agente de IA.