Volver al inicio
Documentación

Servia API

Un endpoint, un mensaje por request. Tu plataforma de automatización (ManyChat u otra) envía cada mensaje del cliente a Servia; Servia responde con el texto para enviar y señales estructuradas para rutear tu flujo. El «cerebro» — servicios, productos, precios, horarios, equipo, pagos — se configura en tu dashboard, no en el flujo.

Quickstart

1. Consigue tu API key. Al suscribirte, tu key llega por email (se muestra una sola vez) junto con el acceso a tu dashboard.

2. Conecta tu flujo. En ManyChat: Actions → Make External Request, o instala la app de Servia y arrastra la action «AI Conversation Turn» (mapping pre-configurado).

POST https://api.serviaagent.com/v1/turn
Authorization: Bearer <TU_API_KEY>
Content-Type: application/json

{
  "contact_id": "{{user_id}}",
  "message": "{{last_text_input}}",
  "contact_name": "{{first_name}}"
}

3. Mapea la respuesta y rutea. En Response mapping: $.reply → tu campo de respuesta, $.route → tu campo de ruta, y los $.fields.* que uses. Un nodo Send Message envía la respuesta y un nodo Condition sobre la ruta decide qué sigue.

App de ManyChat (integración en 1 click)

La forma más simple: instalá la App «Servia» en tu cuenta de ManyChat, pegá tu API key una sola vez, y en el flow builder arrastrá el bloque «AI Conversation Turn». La URL, la autenticación, el body y el mapping de la respuesta ya vienen configurados — sin JSON, sin mapping manual.

El bloque deja en Custom User Fields listos para tus condiciones: ai_reply, ai_route,ai_status, ai_booking_date, ai_booking_time, ai_booking_service,ai_checkout_url, ai_order_id, ai_price, ai_score, ai_image_url. Opcionalmente podés forzar el modo (Agenda / Vende / Responde) y el idiomaen ese paso — una misma key sirve varios flujos.

Triggers (Servia inicia un flujo tuyo): Appointment booked (recién agendó:date, time, service, pax, client_name) · Appointment reminder due (2–24h antes de la cita, para que TU flujo mande el recordatorio:appointment_id, date, time, service, client_name, business_name) · Purchase completed (el pago de un checkout del asistente se confirmó: order_id, total, currency, product).

¿No querés instalar la app? Todo lo de abajo funciona igual con un External Request — es el mismo endpoint.

Autenticación

Cada request lleva Authorization: Bearer <API_KEY>. Las keys tienen el prefijo sk_servia_, se muestran una sola vez al emitirse y se almacenan hasheadas — si la pierdes, se rota desde el dashboard. Una key inválida responde 401; todo lo demás responde 200 siempre (ver «Errores»).

POST /v1/turn

Request

CampoRequeridoDescripción
contact_idId del contacto en tu plataforma ({{user_id}} en ManyChat). La memoria del asistente es por contacto: el cliente vuelve días después y el bot recuerda.
messageEl texto del cliente (se acepta text como alias).
contact_nameNoNombre visible del contacto; se usa para crear la ficha del cliente en el primer mensaje.
request_idNoClave de idempotencia. Si no la envías, un hash de (contacto, mensaje) deduplica los dobles disparos accidentales por una ventana corta — los reintentos de ManyChat son seguros.
modeNoModo del asistente para ESTE turno: book (agenda), sell (vende) o answer (solo responde). Pisa el modo por defecto de la key — así una sola key sirve varios flujos (uno de ventas, otro de agenda). Un valor inválido se ignora y se usa el default de la key.
languageNoIdioma para este turno: es o en. Pisa el idioma por defecto de la key; inválido → default.

Response — el sobre siempre-200

{
  "status": "ok",
  "reply": "¡Listo! Te agendé el corte con Vale el jueves 21 a las 10:00.",
  "route": "booked",
  "fields": {
    "booking_date": "2026-08-21",
    "booking_time": "10:00",
    "booking_service": "Corte de pelo"
  },
  "handoff": false,
  "ms": 2841
}
CampoDescripción
statusSalud del turno: ok · timeout · error · rate_limited · disabled · quota_exhausted. Distinto de okreply puede venir vacío: envía tu mensaje de respaldo.
replyEl texto a enviar al cliente, tal cual.
routeAdónde debe ir tu flujo (tabla abajo). Derivada de hechos observados — «booked» significa que la cita YA existe en el calendario, no que el modelo dijo que la agendó.
fieldsMapa plano de strings para mapear con JSON path (tabla abajo). Solo trae las keys relevantes al turno.
handofftrue si la conversación pasó a modo humano (Live Chat).
attachmentsFotos del catálogo propuestas este turno: [{ url, caption? }]. fields.image_url refleja la primera.
productsProductos recomendados este turno: [{ id, name, price, currency, image?, variant? }]. Mapeable por índice ($.products[0].image); fields.product_id refleja el primero.
msMilisegundos que tomó el turno (diagnóstico).

Rutas (route)

routeQué hacer en tu flujo
continueNada especial: enviar reply y esperar el próximo mensaje (cada mensaje del cliente vuelve a disparar el flujo).
bookedLa cita quedó agendada en el calendario. Confirmación, tags, CRM.
checkoutSe generó un link de pago este turno. El reply ya lo incluye; fields.checkout_url te lo da aparte si quieres tu propio botón.
purchasedEl pago fue confirmado por el proveedor. Se emite EXACTAMENTE UNA VEZ por orden — dispara tu post-venta. Con la app instalada también llega como trigger.
handoffPasar a un humano (Live Chat de tu plataforma). El asistente deja de responder hasta que la conversación vuelva a automático.
fallbackEl asistente no pudo generar respuesta y sirvió una disculpa estática. Puedes reemplazarla por tu propio mensaje de respaldo.

Campos (fields.*)

KeyAparece cuando…
booking_date…se agendó una cita (route=booked). Formato YYYY-MM-DD.
booking_time…se agendó una cita. Formato HH:mm.
booking_service…se agendó una cita: nombre del servicio.
booking_pax…la cita es para más de una persona.
checkout_url…se generó un link de pago (route=checkout).
order_id…se generó un checkout o se confirmó una compra: id de la orden.
price…hay checkout o compra: monto total.
currency…hay checkout o compra: moneda (MXN, USD, ARS…).
product…el turno giró en torno a un producto: su nombre.
product_id…hay productos recomendados o vendidos: id del primero.
image_url…el asistente propuso fotos: URL de la primera.
qualification_score…en modo sell: puntaje de calificación del lead.
mode…siempre: el modo efectivo con el que corrió el turno (book/sell/answer) — útil para depurar overrides por request.
language…siempre: el idioma efectivo del turno (es/en).

POST /v1/turn/dynamic

El mismo pipeline, con la respuesta en formato Dynamic Block de ManyChat (version: v2 + content.messages): úsalo en un bloque Dynamic y ManyChat renderiza directo, sin mapping. Qué envía:

  • Galería de productos — si el turno recomendó productos con foto, llegan como carrusel de cards (Messenger e Instagram lo renderizan nativo; en canales sin cards ManyChat degrada a texto + fotos).
  • Botón «Pagar ahora» — si el turno generó un checkout, debajo de la respuesta va un botón URL con el link de pago (y el reply conserva el link en texto para canales sin botones).
  • Las señales de /v1/turn (status, route, fields, handoff) viajan como keys extra que el renderer ignora. Si tu flujo necesita rutear, usa /v1/turn con response mapping.

Modos del asistente

Cada API key opera en un modo, configurable desde el dashboard: book (agenda citas), sell (vende productos y califica leads) o answer (responde preguntas del negocio, sin agendar ni vender). Idioma es o en. Los precios, el stock y la disponibilidad salen siempre de tu catálogo — el asistente jamás inventa un precio ni confirma una cita que no existe.

Límites y garantías

  • Cada mensaje del cliente = 1 request = 1 mensaje de tu plan. Avisos por email al 80% y 100% del cupo.
  • Al agotarse el cupo, según la política configurada en tu cuenta: pausa hasta el próximo período (default), upgrade automático de plan, o crédito prepagado. El sobreuso se factura a US$0.02 por mensaje.
  • Respuesta siempre <10 s (deadline interno de 8.5 s; si se excede, status=timeout y tu fallback responde).
  • Reintentos seguros: deduplicación por request_id y por (contacto, mensaje); los mensajes de un mismo contacto se procesan en serie.
  • Rate limit de red: 300 requests/min. Los controles reales son por key (tope diario) y por contacto.

Errores

Filosofía: ManyChat no puede rutear respuestas no-200, así que todo request autenticado responde 200 y el resultado viaja en status. Solo dos excepciones, ambas señales de configuración: 401 (API key inválida o ausente) y 404 (el API no está habilitado para tu cuenta). Si contact_id o message faltan, recibes 200 con status=error y reply vacío.

Soporte

¿Dudas o un caso que no cubre esta página? Escríbenos a info@saviabot.com — respondemos en horas hábiles.