Atenta · API pública

La atención por WhatsApp de tu negocio, abierta a tus herramientas. · OpenAPI 3.1: /v1/openapi.json

Un token por negocio (`atk_<slug>_…`, se genera en Ajustes → Integraciones de la app). Misma semántica que la app: cada ruta es una ruta del negocio y el token acota qué puede tocar (permisos). Además de las rutas documentadas aquí, cualquier ruta del negocio de solo lectura o de escritura permitida funciona en `/v1/<ruta>` con las mismas reglas; lo que solo se hace desde la app (aprobar la base, encender, cobrar el plan, campañas, borrar) responde 403 `solo_desde_la_app`. Límite: 120 llamadas por minuto por token. Los teléfonos de los clientes llegan redactados.

Autenticación

Authorization: Bearer atk_<slug>_<32 hex>

El token se crea en la app de Atenta (Ajustes → Integraciones) con los permisos que necesites; se enseña una sola vez.

Rutas

GET /v1/conversaciones

atenta.chats.listar — Lista las conversaciones de WhatsApp del negocio (fijadas primero, luego las que te necesitan, luego por actividad). Filtros: todas | te_necesitan | tu_al_mando | sin_leer | pedidos | resueltas | archivadas; q busca por nombre, teléfono (≥4 dígitos) o texto. Permiso: leer_chats.

GET /v1/conversaciones/{id}

atenta.chats.leer — Lee una conversación completa (mensajes con autor cliente | atenta | persona, estado ✓/✓✓, tipo, media). Marca los mensajes como leídos. Permiso: leer_chats.

POST /v1/conversaciones/{id}/mensajes

atenta.chats.escribir — Manda un mensaje al cliente en esa conversación como persona del negocio (o guarda una nota interna que el cliente no ve). Fuera de la ventana de 24 h de WhatsApp responde 409 fuera_de_ventana: entonces usa una plantilla aprobada. En un negocio de prueba solo llega a sus números de prueba. Permiso: escribir_chats.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "texto": {
   "description": "Texto para el cliente",
   "type": "string",
   "minLength": 1,
   "maxLength": 4000
  },
  "nota": {
   "description": "Nota interna (no sale al cliente)",
   "type": "string",
   "minLength": 1,
   "maxLength": 4000
  },
  "plantilla": {
   "description": "Plantilla aprobada de Meta, para escribir fuera de la ventana de 24 h",
   "type": "object",
   "properties": {
    "nombre": {
     "type": "string"
    },
    "variables": {
     "type": "array",
     "items": {
      "type": "string"
     }
    }
   },
   "required": [
    "nombre"
   ]
  }
 },
 "required": [],
 "additionalProperties": false
}

POST /v1/conversaciones/{id}/control

atenta.chats.tomar_control — Toma el control de la conversación: Atenta deja de contestar y una persona sigue desde aquí. Permiso: escribir_chats.

Cuerpo (JSON)
{
 "type": "object",
 "required": [
  "modo"
 ],
 "properties": {
  "modo": {
   "type": "string",
   "enum": [
    "persona",
    "atenta"
   ],
   "description": "persona = una persona toma el control; atenta = se lo devuelve"
  }
 }
}

GET /v1/crm/pedidos

atenta.pedidos.listar — Lista pedidos del negocio (con cliente, items, total, estado y pago). Permiso: pedidos.

POST /v1/crm/clientes/{cliente_id}/pedidos

atenta.pedidos.crear — Crea un pedido para un cliente (items con nombre, cantidad y precio; el total se calcula si no viene). Permiso: pedidos.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "items": {
   "minItems": 1,
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "nombre": {
      "type": "string",
      "minLength": 1
     },
     "cantidad": {
      "default": 1,
      "type": "number",
      "exclusiveMinimum": 0
     },
     "precio": {
      "type": "number",
      "minimum": 0
     }
    },
    "required": [
     "nombre"
    ]
   }
  },
  "total": {
   "type": "number",
   "minimum": 0
  },
  "direccion": {
   "type": "string",
   "maxLength": 300
  },
  "notas": {
   "type": "string",
   "maxLength": 1000
  },
  "estado": {
   "type": "string",
   "enum": [
    "nuevo",
    "confirmado"
   ]
  }
 },
 "required": [
  "items"
 ],
 "additionalProperties": false
}

PUT /v1/crm/pedidos/{id}

atenta.pedidos.actualizar — Cambia el estado o las notas de un pedido (nuevo → confirmado → en_camino → entregado; o cancelado). Permiso: pedidos.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "estado": {
   "type": "string",
   "enum": [
    "nuevo",
    "confirmado",
    "preparando",
    "en_camino",
    "entregado",
    "cancelado"
   ]
  },
  "notas": {
   "type": "string",
   "maxLength": 1000
  }
 },
 "required": [],
 "additionalProperties": false
}

POST /v1/pedidos/{id}/pagar

atenta.pedidos.cobrar — Registra el pago de un pedido (efectivo, transferencia, monedero del cliente o link de pago). Con monedero descuenta saldo (409 saldo_insuficiente si no alcanza). Permiso: finanzas.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "metodo": {
   "type": "string",
   "enum": [
    "efectivo",
    "transferencia",
    "wallet",
    "link"
   ]
  },
  "monto": {
   "description": "Parcial; por defecto el total",
   "type": "number",
   "exclusiveMinimum": 0
  },
  "referencia": {
   "type": "string",
   "maxLength": 80
  }
 },
 "required": [
  "metodo"
 ],
 "additionalProperties": false
}

GET /v1/citas

atenta.citas.listar — Citas del negocio en un rango de fechas. Permiso: citas.

POST /v1/citas

atenta.citas.crear — Agenda una cita (inicio ISO; duración por defecto la del negocio). Permiso: citas.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "inicio": {
   "type": "string",
   "minLength": 10,
   "description": "Inicio (ISO 8601, con zona)"
  },
  "duracion_min": {
   "type": "integer",
   "minimum": 10,
   "maximum": 480
  },
  "nombre": {
   "type": "string",
   "maxLength": 80
  },
  "motivo": {
   "type": "string",
   "maxLength": 200
  },
  "cliente_id": {
   "type": "integer",
   "exclusiveMinimum": 0,
   "maximum": 9007199254740991,
   "description": "Cliente"
  },
  "estado": {
   "type": "string",
   "enum": [
    "solicitada",
    "confirmada"
   ]
  },
  "notas": {
   "type": "string",
   "maxLength": 500
  }
 },
 "required": [
  "inicio"
 ],
 "additionalProperties": false
}

GET /v1/citas/disponibles

atenta.citas.disponibles — Próximos huecos libres dentro del horario del negocio (sin chocar con citas vivas). Permiso: citas.

PUT /v1/citas/{id}

atenta.citas.mover — Mueve una cita a otro inicio (y opcionalmente cambia su duración, estado o notas). Permiso: citas.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "inicio": {
   "type": "string",
   "description": "Nuevo inicio ISO"
  },
  "duracion_min": {
   "type": "integer",
   "minimum": 10,
   "maximum": 480
  },
  "estado": {
   "type": "string",
   "enum": [
    "solicitada",
    "confirmada",
    "atendida",
    "cancelada"
   ]
  },
  "notas": {
   "type": "string",
   "maxLength": 500
  }
 }
}

GET /v1/crm/clientes

atenta.clientes.buscar — Busca clientes por nombre, apodo o teléfono (teléfonos redactados). También filtra por etiqueta, zona o consentimiento. Permiso: clientes.

GET /v1/crm/clientes/{id}

atenta.clientes.ficha — Ficha completa: datos, preferencias, compras, conversaciones, etapa, seguimientos, pagos. Permiso: clientes.

POST /v1/crm/clientes/{id}/nota

atenta.clientes.nota — Agrega una nota al historial del cliente. Permiso: clientes.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "texto": {
   "type": "string",
   "minLength": 1,
   "maxLength": 2000
  }
 },
 "required": [
  "texto"
 ],
 "additionalProperties": false
}

POST /v1/crm/clientes/{id}/seguimientos

atenta.clientes.seguimiento — Programa un seguimiento (fecha + qué hacer) que aparece en «Hoy» del CRM. Permiso: clientes.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "fecha": {
   "type": "string",
   "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
   "description": "YYYY-MM-DD"
  },
  "texto": {
   "type": "string",
   "minLength": 1,
   "maxLength": 500
  }
 },
 "required": [
  "fecha",
  "texto"
 ],
 "additionalProperties": false
}

PUT /v1/crm/clientes/{id}/etiquetas

atenta.clientes.etiquetar — Agrega o quita etiquetas del cliente. Permiso: clientes.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "agregar": {
   "type": "array",
   "items": {
    "type": "string",
    "maxLength": 40
   }
  },
  "quitar": {
   "type": "array",
   "items": {
    "type": "string",
    "maxLength": 40
   }
  }
 },
 "required": [],
 "additionalProperties": false
}

GET /v1/crm/clientes/{id}/wallet

atenta.finanzas.saldo — Saldo del monedero del cliente y sus movimientos. Permiso: finanzas.

POST /v1/crm/clientes/{id}/wallet/movimientos

atenta.finanzas.recargar — Recarga el monedero del cliente (o ajuste / reembolso). Permiso: finanzas. El cuerpo se completa con: {"tipo":"recarga"}.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "monto": {
   "type": "number",
   "exclusiveMinimum": 0
  },
  "concepto": {
   "type": "string",
   "minLength": 1,
   "maxLength": 200
  },
  "tipo": {
   "type": "string",
   "enum": [
    "recarga",
    "ajuste",
    "reembolso"
   ]
  }
 },
 "required": [
  "monto",
  "concepto"
 ],
 "additionalProperties": false
}

POST /v1/creditos/{id}/abonos

atenta.finanzas.abonar — Registra un abono a un crédito (se aplica a las cuotas en orden). Permiso: finanzas.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "monto": {
   "type": "number",
   "exclusiveMinimum": 0
  },
  "metodo": {
   "type": "string",
   "enum": [
    "efectivo",
    "transferencia",
    "wallet",
    "link"
   ]
  },
  "fecha": {
   "type": "string"
  },
  "nota": {
   "type": "string",
   "maxLength": 300
  }
 },
 "required": [
  "monto",
  "metodo"
 ],
 "additionalProperties": false
}

GET /v1/finanzas/cobranza

atenta.finanzas.cobranza — Cuotas por cobrar (hoy, semana, vencidas, todas) con cliente y monto. Permiso: finanzas.

GET /v1/reporte

atenta.reporte.mes — Reporte del mes: conversaciones, respuesta, escalaciones, ventas, cobros, monedero, crédito, clientes, campañas, satisfacción, llamadas; comparado con el mes anterior. Permiso: reportes.

GET /v1/base

atenta.base.leer — La base de respuestas ACTIVA del negocio (descripción, ubicación, horario, contacto, servicios, políticas, FAQ, por confirmar), la persona, el estado y las capacidades. Permiso: base.

POST /v1/parches

atenta.base.proponer — Propone una corrección a la base (pregunta → respuesta correcta). Queda como parche propuesto: el dueño lo acepta y aprueba desde la app. Nunca se aprueba por aquí. Permiso: base.

Cuerpo (JSON)
{
 "type": "object",
 "properties": {
  "pregunta": {
   "type": "string",
   "minLength": 3,
   "maxLength": 300
  },
  "respuesta": {
   "type": "string",
   "minLength": 1,
   "maxLength": 1000
  },
  "conversacion": {
   "type": "string",
   "maxLength": 40
  }
 },
 "required": [
  "pregunta",
  "respuesta"
 ],
 "additionalProperties": false
}

GET /v1/llamadas/historial

atenta.llamadas.historial — Historial de llamadas con IA (resultado, duración, pedido/cita ligados; números redactados). Permiso: reportes.

GET /v1/yo

Quién soy — El negocio de este token, sus permisos, plan y estado.

GET /v1/webhooks

Webhooks salientes — Lista los webhooks del negocio (sin secretos). Permiso: integraciones.

POST /v1/webhooks

Crear webhook — Da de alta un webhook (máximo 5 por negocio). Eventos: mensaje, escalacion, pedido, cita, pago, llamada. Si no mandas `secreto` se genera uno y se devuelve UNA vez. Firma: cabecera X-Atenta-Firma = t=<unix>,v1=<hmac_sha256(secreto, `${t}.${cuerpo}`)>. Permiso: integraciones.

Cuerpo (JSON)
{
 "type": "object",
 "required": [
  "url",
  "eventos"
 ],
 "properties": {
  "url": {
   "type": "string",
   "format": "uri",
   "description": "https://…"
  },
  "eventos": {
   "type": "array",
   "items": {
    "type": "string",
    "enum": [
     "mensaje",
     "escalacion",
     "pedido",
     "cita",
     "pago",
     "llamada"
    ]
   }
  },
  "secreto": {
   "type": "string",
   "minLength": 16,
   "maxLength": 128
  },
  "nombre": {
   "type": "string"
  }
 }
}

DELETE /v1/webhooks/{id}

Quitar webhook

POST /v1/webhooks/{id}/probar

Probar webhook — Manda un evento `ping` firmado al webhook y devuelve el resultado (status, ms).

GET /v1/webhooks/{id}/entregas

Últimas entregas

GET /v1/tokens

Tokens del negocio — Lista los tokens (prefijo, permisos, último uso). Crear tokens solo se hace desde la app. Permiso: integraciones.

POST /v1/alta

Alta de un negocio (partner) — Solo con partner token (atp_…): da de alta un negocio como lo hace el formulario de atenta.mx. Devuelve slug, folio y la sesión inicial del dueño (15 min) para que él entre y verifique con el enlace de su WhatsApp.

Cuerpo (JSON)
{
 "type": "object",
 "required": [
  "negocio",
  "giro",
  "whatsapp"
 ],
 "properties": {
  "negocio": {
   "type": "string"
  },
  "giro": {
   "type": "string"
  },
  "whatsapp": {
   "type": "string"
  },
  "sitio": {
   "type": "string"
  },
  "correo": {
   "type": "string"
  },
  "pais": {
   "type": "string",
   "description": "ISO-2 (MX, US, CO)"
  },
  "horario": {
   "type": "string"
  }
 }
}

GET /v1/tenants

Negocios de este partner

GET /v1/tenants/{slug}/base

Base y estado de un negocio del partner (lectura)

Webhooks salientes

Cada entrega es un POST JSON {evento, tenant, ts, datos} con las cabeceras X-Atenta-Evento, X-Atenta-Entrega y X-Atenta-Firma: t=<unix>,v1=<hmac_sha256(secreto, t + "." + cuerpo)>. Se reintenta 3 veces (1 s, 5 s, 25 s) si no responde 2xx. Con 20 fallos seguidos el webhook se apaga solo y el dueño lo ve en la app.

Atenta es un producto de Kalia Code.