---
name: bentho-api
description: Usa la API v1 de Bentho para preguntar a los documentos de un espacio (con fuentes y confianza), subir o quitar documentos, ajustar la configuración, consultar créditos y usar los módulos del espacio — Agente ventas (atender y vender por chat), Productos (catálogo, precios, stock), Comercial (tarifas de envío), Facturación (órdenes y comprobantes), Contabilidad, Kommo, Marca, Transcripción, Fuentes (fichas con datos de la web) y Landings. Úsala cuando la tarea mencione Bentho, una clave bth_, bentho.ai/api o un «espacio» de Bentho.
---

# Bentho API v1

Documentación completa: https://dev.bentho.ai · Texto para modelos: https://dev.bentho.ai/llms-full.txt

## Lo básico

- Base: `https://bentho.ai/api`. `https://bentho.org/api` sigue valiendo (es la misma API): no cambies integraciones que ya funcionan.
- Autenticación: `Authorization: Bearer bth_<id>.<secreto>`. Léela SIEMPRE de la variable de entorno `BENTHO_KEY`; nunca la escribas en el código ni la muestres.
- JSON salvo la subida de documentos (multipart) y el stream (SSE).
- Llama desde un servidor: la API no admite llamadas desde el navegador (CORS).
- Timeout de cliente: 60 s o más. Una pregunta tarda de 2 a 20 s.

## Referencias

Este archivo es el mapa. El detalle de cada ruta (cuerpo, respuesta, errores literales y notas) está en `references/`, generado de las mismas fichas que https://dev.bentho.ai. Lee SOLO la del módulo que vas a usar, antes de escribir la llamada:

| Parte | Archivo | Qué trae |
| --- | --- | --- |
| Núcleo | `references/nucleo.md` | Claves, errores, espacios, preguntar, documentos, configuración y créditos: las rutas fuera de los módulos. |
| Fuentes | `references/fuentes.md` | Trae la web a los documentos del espacio: fichas con cada dato citado y páginas que se leen tal cual. |
| Transcripción | `references/transcripcion.md` | Convierte notas de voz y audios en texto. |
| Agente ventas | `references/agente.md` | Atiende y vende por chat: entiende qué pide el cliente, cotiza con el catálogo y los envíos del espacio y cierra la orden. |
| Marca | `references/marca.md` | La personalidad del asistente: identidad, tono y tácticas de tu marca. |
| Productos | `references/productos.md` | El catálogo del espacio: productos, precios, inventario y promociones. |
| Comercial | `references/comercial.md` | Tarifas de envío, recargos y beneficios. |
| Facturación | `references/facturacion.md` | Órdenes, total a pagar y revisión de los comprobantes de pago. |
| Contabilidad | `references/contabilidad.md` | Conecta tu software contable: conciliación y exportaciones. |
| Kommo | `references/kommo.md` | Sincroniza leads y conversaciones con tu CRM Kommo. |
| Landings | `references/landing.md` | Crea landings con formulario desde un brief, probadas en un navegador antes de entregarlas. |

## Qué ruta usar

| Tarea                                             | Ruta                                                                                         | Permiso       |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------- |
| Comprobar una clave: espacios y permiso           | `GET /profile` (sin `/api`) → `user.companies`, `user.permiso`                               | cualquiera    |
| Saber a qué espacios llega la clave y sus módulos | `GET /api/companies` → `companies[].id`, `companies[].modules`                               | cualquiera    |
| Saber si cada módulo del espacio funciona         | `GET /api/companies/{espacio}/semaforo` → `modulos.{id}.color` y `motivo`                    | lee           |
| Preguntar                                         | `POST /api/rag/{espacio}/conversations` con `{"question", "session_id"}`                     | lee           |
| Preguntar mostrando el texto en vivo              | `POST /api/rag/{espacio}/conversations/stream` (SSE)                                         | lee           |
| Listar documentos                                 | `GET /api/rag/{espacio}/documents`                                                           | lee           |
| Descargar un documento                            | `GET /api/rag/{espacio}/documents/{archivo}` (binario)                                       | lee           |
| Subir documentos (.pdf .docx .txt .md)            | `POST /api/rag/{espacio}/load_documents`, multipart, campo `files` repetible                 | escribe       |
| Saber si lo subido ya está listo                  | `GET /api/rag/{espacio}/indexing_status` hasta `status` = `done` o `error`                   | lee           |
| Quitar un documento                               | `DELETE /api/rag/{espacio}/documents/{archivo}`                                              | escribe       |
| Vaciar la caché de respuestas                     | `DELETE /api/rag/{espacio}/clear_cache`                                                      | escribe       |
| Leer / ajustar cómo responde                      | `GET` / `PATCH /api/rag/{espacio}/config`                                                    | lee / escribe |
| Límites, cuota diaria, IPs del espacio            | `GET` / `PATCH /api/companies/{espacio}/api-config`                                          | lee / escribe |
| Créditos                                          | `GET /api/companies/{espacio}/cuenta` → `cuenta.id`, luego `GET /api/cuentas/{cuenta}/bolsa` | lee           |
| Gasto de los ciclos cerrados                      | `GET /api/cuentas/{cuenta}/cierres`                                                          | lee           |
| Cupo de módulos del espacio                       | `GET /api/companies/{espacio}/limite`                                                        | lee           |
| Activar o quitar módulos                          | `PATCH /api/companies/{espacio}/modules` con la lista COMPLETA `{"modules": [...]}`          | escribe       |
| Armar una ficha con datos de la web               | `POST /api/mod/fuentes/{espacio}/fichas` con `{"tema", "plantilla"}` → 202 con `id`          | escribe       |
| Seguir una ficha                                  | `GET /api/mod/fuentes/{espacio}/fichas/{ficha}` hasta `status` = `publicado` o `fallido`     | lee           |
| Leer la ficha armada                              | `GET /api/mod/fuentes/{espacio}/fichas/{ficha}/markdown`                                     | lee           |
| Crear una landing desde un brief                  | `POST /api/mod/landing/{espacio}/landings` con `{"prompt", "submitUrl"}` → 202 con `id`      | escribe       |
| Seguir una landing                                | `GET /api/mod/landing/{espacio}/landings/{landing}` hasta que `status` termine               | lee           |
| Bajar el HTML de una landing                      | `GET /api/mod/landing/{espacio}/landings/{landing}/html`                                     | lee           |

## Preguntar bien

- `session_id` es OBLIGATORIO en la práctica (sin él: 400 `"session_id es obligatorio."`). Usa uno por conversación y reúsalo en las preguntas de seguimiento.
- Respuesta: `status_code` `"1000"` = respondió con apoyo en los documentos; `"1001"` = no hay información suficiente, `response` trae el mensaje de rechazo y `sources` va vacío. No reintentes un 1001: dará lo mismo.
- `warning: true` = respaldo parcial; dilo al presentar la respuesta. `confidence` va de 0 a 1.
- `sources` son los documentos citados; `response` termina con el pie «Referencia: …».
- Un error interno llega como 200 con `status_code` `"1001"` y el texto «Ocurrió un error interno procesando la consulta. Intenta de nuevo.»: ahí sí puedes reintentar una vez.

## Stream (SSE)

Tramas `data: {json}` separadas por una línea en blanco. Ignora las líneas que empiezan por `:` (keepalive cada 15 s). Eventos: `status`, `chunk` (`content`), `handoff`, `done` (`status_code`, `full_response`, `confidence`, `warning`, `sources`) y `error` (`content`, cierra el stream). Decide con el `status_code` del `done`, no con los `chunk`.

## Módulos: lo común

- Ruta: `https://bentho.ai/api/mod/{modulo}/{espacio}/{ruta}`, con la misma clave. `{modulo}` es el ID (`agente`, `productos`, `comercial`, `facturacion`, `contabilidad`, `kommo`, `marca`, `transcripcion`, `fuentes`, `landing`), no el nombre.
- Solo responde si el id está en `modules` del espacio (`GET /api/companies`); si no, 403 `módulo no habilitado para este espacio.`. Id inexistente o retirado (`ventas`, `comprension`): 404 `módulo desconocido.`.
- GET vale con cualquier clave; POST, PUT, PATCH y DELETE piden `escribe` (403 `Tu cuenta es de solo lectura en este espacio.`). Excepción: conversar con el Agente ventas vale con `lee`.
- Solo gastan créditos (402 sin saldo): Agente ventas `conversations…`, Fuentes (armar ficha, lanzar fuente) y Landings (crear, refinar, validar, completar). Lo gastado, en créditos: `GET /api/mod/{modulo}/{espacio}/consumo` (Agente ventas y Fuentes).
- 502: el módulo no está disponible; reintenta 2-3 veces con espera creciente.
- Respeta la barra final cuando la ruta la lleva (`products/`, `conversations/`, `leads/`…): sin ella el módulo no devuelve los datos.
- La guía de cada módulo y una ficha por ruta: https://dev.bentho.ai/api/modulos/

## Agente ventas (módulo `agente`)

- Sustituye desde el 2026-10-13 a los módulos `ventas` y `comprension`, que se retiraron: `/api/mod/ventas/…` y `/api/mod/comprension/…` dan 404. Mismo contrato que tenía Ventas: cambia el prefijo por `/api/mod/agente/` y nada más.
- Entiende qué pide cada mensaje en el mismo turno: no hay ruta aparte para interpretarlo.
- En un espacio con `agente`, `POST /api/rag/{espacio}/conversations` (y `/stream`) también llega al agente y responde como él (`estado`, `cotizacion`, `handoff`…).
- Conversar con un cliente: `POST /api/mod/agente/{espacio}/conversations/` con `{"question", "session_id"}` (un `session_id` por chat; reúsalo). Responde con `response`, `status_code`, `estado`, `cotizacion` y `handoff` (pasar a una persona: no lo ignores). Timeout de cliente: 90 s.
- Reiniciar un chat: `DELETE …/sessions/{sesion}`. Imagen del cliente (comprobante): `POST …/conversations/evidence`, multipart.
- Leads: `GET …/leads/`, `GET …/leads/{lead}`, `PATCH …/leads/{lead}` con `{"estado"}`.
- Configuración del agente: `GET` / `PATCH …/leads-config`. Tarifas de envío: `POST …/pricing/tables` (archivo) → revisa → `POST …/pricing/versions/{tabla}/activate`; cotizar: `POST …/pricing/quote`. Inventario: `…/inventory/…`.

## Productos (módulo `productos`)

- Catálogo: `GET` / `POST …/products/`, `GET` / `PATCH` / `DELETE …/products/{producto}`; variantes en `…/products/{producto}/variants` y `…/variants/{variante}`; tipos en `…/product-types/`.
- Buscar: `GET …/catalog/search`. Importar un archivo: `POST …/catalog/import` → revisa `GET …/catalog/imports/{importacion}` → `POST …/catalog/imports/{importacion}/activate` (activarla dos veces duplica productos).
- Precios: listas en `…/price-lists`, precios en `…/prices`; cotizar un carrito con promociones: `POST …/price-quote`. Promociones: `…/promotions`. Para cambiar un precio, fíjalo otra vez con la misma lista, variante, moneda y `min_qty`: reemplaza al anterior (no lo borres antes).
- Stock: `…/inventory/levels`, `…/inventory/items/{variante}`; reservas en `…/inventory/reservations`; venta confirmada: `POST …/inventory/sale`.

## Comercial, Facturación, Contabilidad y Kommo

- Comercial (`comercial`): tarifas de envío por ciudad. Subir `POST …/tarifas/draft` (archivo) → `POST …/tarifas/{carga}/activate`; cotizar un pedido: `POST …/cotizar`; beneficios: `POST …/reglas/evaluar`.
- Facturación (`facturacion`): `POST …/orders` crea la orden con el total a pagar; el comprobante se sube con `POST …/orders/{orden}/evidence` (multipart); se revisa en `GET …/review-queue` y se aprueba o rechaza en `…/review-queue/{comprobante}/approve` o `/reject`. Los comprobantes son datos personales: no los guardes ni los enseñes de más.
- Contabilidad (`contabilidad`): conecta el software con `PATCH …/config` y pruébalo con `POST …/config/test`; manda facturas, pagos o clientes a la cola (`POST …/push/invoice`, `/payment`, `/customer`) y procésala con `POST …/outbox/process`.
- Kommo (`kommo`): conecta con `PATCH …/config` (subdominio y token de larga duración) y prueba con `POST …/config/test`; embudos en `GET …/pipelines`; envíos en `GET …/outbox/`.

## Marca y Transcripción

- Marca (`marca`): `GET` / `PATCH …/config` (identidad, estilo, tácticas). Un PATCH reemplaza cada apartado entero: manda el apartado completo.
- Transcripción (`transcripcion`): `POST …/transcripciones`, multipart con el campo `archivo` (un audio de hasta 25 MB y 120 s) e `idioma`; devuelve el texto.

## Fuentes (módulo)

Solo en espacios con el módulo `fuentes` (sale en `GET /api/companies`); si no, 403 `módulo no habilitado para este espacio.`. Guía: https://dev.bentho.ai/api/fuentes/

- La plantilla es markdown: `## Sección` y una línea `- Nombre: qué buscar` por campo. Sin secciones con campos: 422.
- Armar responde 202 al momento; la ficha tarda minutos. Consulta el estado cada 10-15 s. `publicado` quiere decir armada; entra en los documentos del espacio (`ficha-<tema>.md`), y Bentho la usa al responder, cuando `traza.publicacion.status` es `published`. Con `fallida` se reintenta sola; con `rechazada`, vuelve a armarla. Otra ficha con el mismo tema la reemplaza.
- Cada dato del markdown lleva `Fuente` y `Cita`; los vacíos dicen «sin respaldo en las páginas leídas». No rellenes tú los vacíos.
- Si llenó menos de la mitad, `traza.sugerencia` lo dice: pide a la persona 2-4 URLs del caso y vuelve a armarla con `urls`.
- Con `como.cierre_externo: true`, una búsqueda externa intenta al final llenar los campos vacíos. Lo que no respalda una página leída sale marcado «completado por búsqueda externa, sin página que lo respalde»: dilo al presentar el dato. Gasta créditos a tarifa externa; úsalo solo si la persona lo pide.
- Para comprobar un dato: `GET /api/mod/fuentes/{espacio}/fichas/{ficha}/pagina?url=<url de traza.paginas>` da el texto que leyó la ficha.
- Armar una ficha y lanzar una fuente gastan créditos (402 sin saldo).

## Landings (módulo)

Solo en espacios con el módulo `landing` (sale en `GET /api/companies`); si no, 403 `módulo no habilitado para este espacio.`. Guía: https://dev.bentho.ai/api/landings/

- Crear responde 202 al momento; la landing tarda minutos. Consulta el estado cada 10-15 s. No vuelvas a crearla para «reintentar»: gastarías otra vez.
- `status`: `pendiente`, `generando`, `aplazado` (sigue sola) → espera. `esperando_datos` → enseña a la persona las `pregunta` de `versiones[0].faltantes` y manda sus respuestas a `POST …/landings/{landing}/completar` con `{"respuestas": {clave: texto}, "omitir": [clave]}`. No inventes las respuestas. `aprobado` → lista. `revision` → hay HTML, pero `calidad.motivos` dice qué no pasó. `fallido` / `cancelado` → mira `error`.
- Cambios: `POST …/refinar` con `{"prompt": "qué cambiar"}`. Una sola versión en curso por landing (409). Cancelar: `POST …/cancelar`. Volver a una versión anterior, sin gastar: `POST …/restaurar` con `{"version": n}`.
- El formulario envía JSON a `submitUrl` desde el navegador y espera `{"success": true}`: si está en otro dominio, necesita CORS.
- Crear, refinar, validar y completar gastan créditos (402 sin saldo).

## Errores: qué hacer

Siempre `{"detail": "…"}` (422: lista; 402: objeto con `motivo`).

| Status          | Qué hacer                                                                                                                                                                                                                             |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401             | Clave ausente, inválida o revocada. No reintentes: pide una clave válida.                                                                                                                                                             |
| 402             | `motivo` `pago_vencido`/`suspension_comercial` (cuenta) o `bolsa_agotada` (créditos, trae `renueva`). No reintentes.                                                                                                                  |
| 403             | Espacio fuera de alcance, prueba vencida, API apagada, IP no autorizada, clave `lee` en una escritura, campo que solo cambia Bentho, módulo que el espacio no tiene, gestión de claves con una clave. Lee el `detail`; no reintentes. |
| 404 / 405 / 422 | Corrige la petición.                                                                                                                                                                                                                  |
| 413             | Subida > 200 MB, > 20 archivos o un archivo > 50 MB. Divide.                                                                                                                                                                          |
| 429             | Espera `Retry-After` (segundos) y reintenta. Sin la cabecera: espera creciente.                                                                                                                                                       |
| 502 / 503       | Reintenta 2-3 veces con espera creciente.                                                                                                                                                                                             |

## Límites y créditos

- 120 peticiones por minuto por clave (ventana deslizante). Por espacio: 2/s con ráfaga de 120 por defecto y cuota diaria opcional (UTC), configurables en `api-config`.
- Gastan créditos las preguntas, la indexación, conversar con el Agente ventas, las fichas de Fuentes y las landings; sin créditos, esas rutas dan 402 y las demás siguen funcionando. `gastados` y `restantes` de la bolsa son TEXTO decimal (`"0.3426"`): conviértelos con un tipo decimal.

## No hagas

- No inventes rutas ni campos: si no está aquí, búscalo en `references/` (o en https://dev.bentho.ai/llms-full.txt si la skill se instaló sin ellas).
- No cambies `activa` a `false` en `api-config` con la misma clave con la que trabajas: te dejas fuera.
- No uses una clave `escribe` si la tarea solo pregunta o lee.
- No intentes crear ni revocar claves con una clave: `/api/tokens` solo funciona con la sesión de la consola.
- No mandes en `PATCH …/modules` solo el módulo nuevo: la lista es la completa y lo que falte se quita.
