Bots API

Usar la IA de Sendeasy desde tu propia aplicación — un asistente dentro de tu producto, una rutina en tu backend, una pantalla que resume documentos — sin pasar por WhatsApp.

El bot es quien carga las instrucciones: lo creas y editas en el panel, y aquí indicas el botId. Cambiar el comportamiento de la IA es editar el bot, no cambiar tu código.

Requisitos previos

  1. API Token del proyecto — en Integraciones → WABA → sección API Tokens, donde creas un token con nombre y puedes revocarlo. Es el mismo token de la WABA API y de la Email API: uno por proyecto, no uno por producto.
  2. Un bot creado en el panel, con sus instrucciones y fuentes de conocimiento — consulta /es/bot. Guarda el botId.
  3. Créditos de bot disponibles en el plan del proyecto.

Usa GET /api/v1/ai/health para verificar la integración sin gastar crédito.

Autenticación

Header obligatorio:

Authorization: Bearer <api_token>

El token identifica el proyecto, y es él quien autoriza el botId: un bot de otro proyecto es rechazado, aunque conozcas el id.

Endpoints

MétodoEndpointFinalidadCrédito
POST/api/v1/ai/completionGenerar texto con el prompt del bot1 por generación
POST/api/v1/ai/extractExtraer contenido de un PDF1 por archivo
POST/api/v1/ai/searchBuscar en la base de conocimiento del botno consume
GET/api/v1/ai/healthDiagnóstico: ¿la integración está en pie?no consume

Límite: 60 solicitudes por minuto por API Token (429 ERR_PUBLIC_AI_RATE_LIMIT). El conteo es por token, no por IP: varios servidores que usan el mismo token comparten la cuota, y el mismo servidor con tokens distintos tiene cuotas separadas.

Generación de texto

POST /api/v1/ai/completion

Payload

CampoTipoObligatorioObservaciones
promptstringel pedido en sí, hasta 120.000 caracteres
botIdstringUno de los dosusa las instrucciones y el conocimiento de ese bot
instructionsstringUno de los dossystem prompt suelto, hasta 60.000 caracteres
responseFormatstringNotext (predeterminado) o json
timeoutMsnumberNoentre 1.000 y 90.000; predeterminado del servicio si se omite

Indica botId o instructions. Sin ninguno de los dos la ruta responde 400, en lugar de gastar crédito para devolver texto fuera de contexto.

Ejemplo

curl --location 'https://backend.sendeasy.app/api/v1/ai/completion' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer TU_API_TOKEN' \
  --data '{
    "botId": "tu-bot-id",
    "prompt": "Resume en dos párrafos la política de devoluciones."
  }'

Respuesta de éxito:

{
  "success": true,
  "result": "La política de devoluciones permite devolver en hasta 30 días..."
}

Con "responseFormat": "json", la respuesta llega parseada en dados en lugar de result — útil cuando el prompt pide una estructura y no quieres tratar el texto:

{
  "success": true,
  "dados": { "prazo_dias": 30, "exige_nota": true }
}

Extracción de PDF

POST /api/v1/ai/extract

Envío multipart/form-data con el archivo en el campo file. Solo PDF, hasta 25 MB.

CampoTipoObligatorioObservaciones
filefileel PDF, application/pdf
modestringNotext (predeterminado) devuelve el texto en result; otros modos devuelven el payload en dados
curl --location 'https://backend.sendeasy.app/api/v1/ai/extract' \
  --header 'Authorization: Bearer TU_API_TOKEN' \
  --form 'file=@"/ruta/contrato.pdf"' \
  --form 'mode="text"'
{
  "success": true,
  "result": "CONTRATO DE PRESTACIÓN DE SERVICIOS..."
}

La lectura usa OCR cuando el PDF está escaneado, así que los archivos grandes tardan. Si la IA no reconoce el contenido, la respuesta es 502 con la explicación del motivo — reenviar el mismo archivo no lo resuelve.

Búsqueda en la base de conocimiento

POST /api/v1/ai/search

Recupera fragmentos de las fuentes del bot, sin generar texto. Sirve para fundamentar una respuesta tuya, o para mostrar al usuario de dónde salió la información.

CampoTipoObligatorioObservaciones
botIdstringen qué bot buscar
querystringqué buscar, hasta 2.000 caracteres
topKnumberNocuántos fragmentos devolver, de 1 a 8
filtersobjectNorestringe la búsqueda a ciertos documentos (ver abajo)

filters acepta dos campos, ambos listas de patrones de nombre de archivo (% coincide con cualquier tramo):

CampoEfecto
incluirArquivosbusca solo en los documentos que coincidan; omitido, recorre toda la base
excluirArquivosdescarta los documentos que coincidan, aunque estén incluidos
{
  "botId": "tu-bot-id",
  "query": "plazo de garantía",
  "filters": {
    "incluirArquivos": ["manual-%", "politica-cambios.pdf"],
    "excluirArquivos": ["borrador-%"]
  }
}

Sirve cuando la base es grande y ya sabes dónde está la respuesta: sin filtro, un documento extenso puede ocupar los lugares del resultado y tapar lo que importa.

curl --location 'https://backend.sendeasy.app/api/v1/ai/search' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer TU_API_TOKEN' \
  --data '{
    "botId": "tu-bot-id",
    "query": "plazo de garantía",
    "topK": 3
  }'
{
  "success": true,
  "trechos": [
    {
      "texto": "La garantía legal es de 90 días para productos duraderos...",
      "procedencia": "manual-del-cliente.pdf",
      "score": 0.82
    }
  ]
}

No consume crédito: es recuperación de contenido, no generación. Si la búsqueda falla, la respuesta llega con trechos: [] en lugar de error — sin contexto tu respuesta pierde fundamento, no deja de existir.

Diagnóstico de la integración

GET /api/v1/ai/health

No consume crédito y no invoca al modelo. Responde las dos preguntas detrás de casi toda falla de integración: ¿el servicio de IA está en línea y todavía hay saldo?

curl --location 'https://backend.sendeasy.app/api/v1/ai/health' \
  --header 'Authorization: Bearer TU_API_TOKEN'
{
  "success": true,
  "companyId": 42,
  "botrag": { "ok": true, "latenciaMs": 210 },
  "creditos": { "disponivel": 4820, "mes": "9/2026" },
  "checkedAt": "2026-09-01T12:30:00.000Z"
}
  • botrag.ok: false — el servicio de IA no está disponible; un campo detalhe acompaña la causa. Nada que hacer de tu lado salvo reintentar más tarde.
  • creditos.disponivel: 0 — el proyecto se quedó sin créditos y las rutas de generación responderán 402. Renueva el plan o espera la franquicia del mes siguiente.

A qué bots llega el token

El botId se resuelve dentro del proyecto de tu API Token. Un token de un proyecto no puede usar el bot de otro, aunque conozca el id: la ruta responde 403 sin generar nada ni tocar tu saldo. Un bot que no existe responde 404.

Aplica a completion y search, las dos rutas que resuelven un bot. extract no usa botId.

Créditos y reembolso

  • Cada generación (completion, extract) descuenta 1 crédito de bot del proyecto.
  • Sin crédito, la ruta responde 402 ERR_NO_BOT_CREDITS antes de cualquier cobro.
  • Si la generación falla después del cobro, el crédito se reembolsa automáticamente y la ruta responde 502.
  • search y health no consumen nada.

Códigos de error

HTTPerrorCuándo ocurre
400mensaje de validaciónpayload inválido, prompt ausente, ni botId ni instructions, archivo que no es PDF
400INVALID_JSONel cuerpo no es JSON válido
400FILE_TOO_LARGEPDF por encima de 25 MB
401ERR_API_TOKEN_NOT_PROVIDED / ERR_API_TOKEN_INVALID_FORMAT / ERR_API_TOKEN_INVALID / ERR_API_TOKEN_AUTHENTICATION_FAILEDheader ausente o mal formado, token inválido o revocado
402ERR_NO_BOT_CREDITSproyecto sin créditos de bot (no se cobró nada)
403mensaje de autorizaciónbotId de un bot que no pertenece al proyecto del token
404mensaje de botbotId inexistente
413PAYLOAD_TOO_LARGEcuerpo JSON por encima de 10 MB
429ERR_PUBLIC_AI_RATE_LIMITmás de 60 solicitudes por minuto
502mensaje en textofalla al generar (crédito reembolsado); cuando la IA sabe el motivo, viene en el mensaje
504GATEWAY_TIMEOUTla generación superó el tiempo límite

Bots API × bot en WhatsApp

El mismo bot, dos caminos — lo que cambia es quién conduce la conversación:

Bots API (/api/v1/ai/*)Bot en atención
Quién llamatu aplicaciónel ticket, cuando entra en el sector
Conversacióncada llamada es independienteSendeasy mantiene el historial en el ticket
Uso típicoasistente y automatizaciones en tu productoatención en WhatsApp

Essa informação foi útil?