# Especificación de Endpoints — ERP Palmas360 ↔ Bot WhatsApp > **Para el equipo de Palmas360:** Este documento describe todos los endpoints que el ERP debe implementar para que el bot de WhatsApp funcione correctamente. Los endpoints marcados con ⚠️ actualmente apuntan a URLs de prueba (`httpbin.org/post`) y deben ser reemplazados con las URLs reales del ERP. --- ## Autenticación Todas las llamadas del bot al ERP incluyen dos headers de autenticación: ``` Authorization: Bearer {api_key} X-API-Key: {api_key} ``` El `api_key` es la clave configurada para Palmas360 en el bot. Validar cualquiera de los dos headers es suficiente. --- ## Resumen de endpoints | # | Tipo | Endpoint ERP | Descripción | Estado | |---|------|--------------|-------------|--------| | 1 | GET | `/fincas` | Lista de fincas activas | Pendiente | | 2 | GET | `/ciclos/cosecha` | Informe ciclos cosecha | Pendiente | | 3 | GET | `/ciclos/sanidad/censo` | Informe ciclos censo | Pendiente | | 4 | GET | `/ciclos/sanidad/plagas` | Informe ciclos plagas | Pendiente | | 5 | GET | `/ciclos/sanidad/palm` | Informe RHYN. PALM. | Pendiente | | 6 | GET | `/ciclos/sanidad/tratamientos` | Informe ciclos tratamientos | Pendiente | | 7 | GET | `/ciclos/polinizacion` | Informe ciclos polinización | Pendiente | | 8 | GET | `/produccion/kilos-finca` | Kilos facturados por finca | Pendiente | | 9 | GET | `/produccion/kilos-lotes` | Kilos por lotes (rango fechas) | Pendiente | | 10 | GET | `/mantenimiento` | Ciclos mantenimiento a la fecha | Pendiente | | 11 | POST | `/ciclos/cosecha` | Registrar ciclo cosecha | ⚠️ Test | | 12 | POST | `/ciclos/sanidad` | Registrar ciclo sanidad | ⚠️ Test | | 13 | POST | `/ciclos/polinizacion` | Registrar ciclo polinización | ⚠️ Test | | 14 | POST | `/tiquetes` | Registrar tiquete báscula | ⚠️ Test | | 15 | POST | `/ausentismos` | Registrar ausentismo | ⚠️ Test | | 16 | POST | `/pluviometria` | Registrar lecturas pluviometría | ⚠️ Test | --- ## Endpoints de DESCARGA (GET) — Bot consulta, ERP responde con archivo El bot llama estos endpoints y reenvía la respuesta como documento al usuario de WhatsApp. **La respuesta debe ser un archivo descargable** (PDF o Excel). ### 1. Lista de fincas Usado para mostrar la lista de fincas en flujos dinámicos (Producción kilos por finca, Pluviometría). ``` GET {url_base}/fincas Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} ``` **Respuesta esperada (JSON, 200):** ```json [ { "id": "finca_001", "label": "Finca La Palma" }, { "id": "finca_002", "label": "Finca El Diamante" }, { "id": "finca_003", "label": "Finca Los Almendros" } ] ``` > El campo `id` es el valor que el bot usará internamente; `label` es lo que ve el usuario en WhatsApp. --- ### 2. Ciclos cosecha ``` GET {url_base}/ciclos/cosecha Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) — fecha inicio del período fecha_hasta (YYYY-MM-DD) — fecha fin del período ``` El bot envía automáticamente: - **"Día actual"** → `fecha_desde` y `fecha_hasta` = hoy - **"Histórico 30 días"** → `fecha_desde` = hace 30 días, `fecha_hasta` = hoy **Respuesta esperada:** Archivo binario (PDF o Excel) ``` Content-Type: application/pdf Content-Disposition: attachment; filename="ciclos_cosecha.pdf" [bytes del archivo] ``` --- ### 3. Ciclos sanidad — Censo ``` GET {url_base}/ciclos/sanidad/censo Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel. --- ### 4. Ciclos sanidad — Plagas ``` GET {url_base}/ciclos/sanidad/plagas Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel. --- ### 5. Ciclos sanidad — RHYN. PALM. ``` GET {url_base}/ciclos/sanidad/palm Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel. --- ### 6. Ciclos sanidad — Tratamientos ``` GET {url_base}/ciclos/sanidad/tratamientos Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel. --- ### 7. Ciclos polinización ``` GET {url_base}/ciclos/polinizacion Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel. --- ### 8. Producción kilos por finca ``` GET {url_base}/produccion/kilos-finca Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: finca_id — ID de la finca seleccionada por el usuario (viene de /fincas) fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel con kilos facturados para esa finca. --- ### 9. Producción kilos por lotes ``` GET {url_base}/produccion/kilos-lotes Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) — ingresada por el usuario fecha_hasta (YYYY-MM-DD) — ingresada por el usuario ``` **Respuesta:** Archivo PDF o Excel con kilos por lote en el rango de fechas. --- ### 10. Mantenimiento ``` GET {url_base}/mantenimiento Headers: Authorization: Bearer {api_key} X-API-Key: {api_key} Query params: fecha_desde (YYYY-MM-DD) fecha_hasta (YYYY-MM-DD) ``` **Respuesta:** Archivo PDF o Excel con ciclos de mantenimiento. --- ## Endpoints de SUBIDA (POST) — Bot envía datos capturados del usuario ⚠️ El bot guía al usuario campo por campo, muestra un resumen, pide confirmación, y luego hace un POST al ERP con los datos. El usuario que envía incluye siempre su número de teléfono y nombre de perfil de WhatsApp. **Headers en todos los POST:** ``` Content-Type: application/json Authorization: Bearer {api_key} X-API-Key: {api_key} ``` **Respuesta esperada en todos los POST (200):** ```json { "status": "ok", "message": "Registro guardado correctamente" } ``` Si hay error (400/500): ```json { "status": "error", "message": "Descripción del error" } ``` --- ### 11. ⚠️ Registrar ciclo cosecha ``` POST {url_base}/ciclos/cosecha ``` **Body JSON:** ```json { "fecha": "2026-06-30", "finca": "La Palma", "lote": "Lote 3A", "racimos": "120", "telefono": "573168950803", "nombre": "Juan Pérez" } ``` | Campo | Tipo | Descripción | |-------|------|-------------| | `fecha` | string (YYYY-MM-DD o texto libre) | Fecha del ciclo ingresada por el usuario | | `finca` | string | Nombre de la finca | | `lote` | string | Identificador del lote | | `racimos` | string | Cantidad de racimos | | `telefono` | string | Número WhatsApp del usuario que reporta | | `nombre` | string | Nombre del perfil WhatsApp del usuario | --- ### 12. ⚠️ Registrar ciclo sanidad ``` POST {url_base}/ciclos/sanidad ``` **Body JSON:** ```json { "fecha": "2026-06-30", "finca": "La Palma", "tipo_ciclo": "Censo", "observaciones":"Sin novedades", "telefono": "573168950803", "nombre": "Juan Pérez" } ``` | Campo | Tipo | Descripción | |-------|------|-------------| | `fecha` | string | Fecha del ciclo | | `finca` | string | Nombre de la finca | | `tipo_ciclo` | string | Tipo de ciclo (Censo, Plagas, RHYN, Tratamiento…) | | `observaciones` | string | Observaciones libres del usuario | | `telefono` | string | Número WhatsApp | | `nombre` | string | Nombre perfil WhatsApp | --- ### 13. ⚠️ Registrar ciclo polinización ``` POST {url_base}/ciclos/polinizacion ``` **Body JSON:** ```json { "fecha": "2026-06-30", "finca": "La Palma", "lote": "Lote 2B", "palmas_polinizadas": "85", "telefono": "573168950803", "nombre": "Juan Pérez" } ``` | Campo | Tipo | Descripción | |-------|------|-------------| | `fecha` | string | Fecha del ciclo | | `finca` | string | Nombre de la finca | | `lote` | string | Lote trabajado | | `palmas_polinizadas` | string | Número de palmas polinizadas | | `telefono` | string | Número WhatsApp | | `nombre` | string | Nombre perfil WhatsApp | --- ### 14. ⚠️ Registrar tiquete báscula ``` POST {url_base}/tiquetes ``` **Body JSON:** ```json { "fecha": "2026-06-30", "numero_tiquete": "T-00452", "finca": "El Diamante", "kilos": "3450", "telefono": "573168950803", "nombre": "Juan Pérez" } ``` | Campo | Tipo | Descripción | |-------|------|-------------| | `fecha` | string | Fecha del tiquete | | `numero_tiquete` | string | Número del tiquete de báscula | | `finca` | string | Finca de origen | | `kilos` | string | Kilos registrados en báscula | | `telefono` | string | Número WhatsApp | | `nombre` | string | Nombre perfil WhatsApp | --- ### 15. ⚠️ Registrar ausentismo ``` POST {url_base}/ausentismos ``` **Body JSON:** ```json { "fecha": "2026-06-30", "empleado": "Carlos Ramírez", "motivo": "Incapacidad médica", "dias": "3", "telefono": "573168950803", "nombre": "Juan Pérez" } ``` | Campo | Tipo | Descripción | |-------|------|-------------| | `fecha` | string | Fecha de inicio del ausentismo | | `empleado` | string | Nombre del empleado ausente | | `motivo` | string | Motivo del ausentismo | | `dias` | string | Días de ausentismo | | `telefono` | string | Número WhatsApp | | `nombre` | string | Nombre perfil WhatsApp | --- ### 16. ⚠️ Registrar pluviometría Este endpoint es diferente: el bot pregunta el valor por cada finca (usando la lista de `/fincas`) y envía **un array** con todas las lecturas en una sola llamada. ``` POST {url_base}/pluviometria ``` **Body JSON:** ```json { "fecha": "2026-06-30", "telefono": "573168950803", "nombre": "Juan Pérez", "lecturas": [ { "id": "finca_001", "label": "Finca La Palma", "valor": "45" }, { "id": "finca_002", "label": "Finca El Diamante", "valor": "38" }, { "id": "finca_003", "label": "Finca Los Almendros", "valor": "52" } ] } ``` | Campo | Tipo | Descripción | |-------|------|-------------| | `fecha` | string | Fecha de la medición | | `telefono` | string | Número WhatsApp | | `nombre` | string | Nombre perfil WhatsApp | | `lecturas[].id` | string | ID de la finca (viene de `/fincas`) | | `lecturas[].label` | string | Nombre de la finca | | `lecturas[].valor` | string | Milímetros registrados (texto libre del usuario) | --- ## Formato de respuesta para archivos (endpoints GET) El bot espera recibir el archivo directamente en la respuesta HTTP. Formatos soportados: | Content-Type | Extensión | Notas | |---|---|---| | `application/pdf` | `.pdf` | Preferido para informes | | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` | `.xlsx` | Excel moderno | | `application/vnd.ms-excel` | `.xls` | Excel legacy | **Headers recomendados en la respuesta:** ``` Content-Type: application/pdf Content-Disposition: attachment; filename="reporte_cosecha_2026-06-30.pdf" Content-Length: {tamaño en bytes} ``` > Si el archivo pesa más de **16 MB**, WhatsApp rechazará el envío. Para reportes grandes, considerar dividirlos por período o reducir el rango de fechas. --- ## Configuración en el bot Una vez que el ERP tenga los endpoints listos, hay que actualizar las URLs en: **Admin → Bot Config → Endpoints** (`https://admin.palmas360.com/admin/bot-config?id=2`) Los `endpoint_key` que debe buscar y actualizar son: | endpoint_key | URL actual (test) | URL real a colocar | |---|---|---| | `fincas_list_dn` | — | `{url_base}/fincas` | | `cosecha_dn` | — | `{url_base}/ciclos/cosecha` | | `ciclo_censo_dn` | — | `{url_base}/ciclos/sanidad/censo` | | `ciclo_plagas_dn` | — | `{url_base}/ciclos/sanidad/plagas` | | `ciclo_palm_dn` | — | `{url_base}/ciclos/sanidad/palm` | | `ciclo_tratamiento_dn` | — | `{url_base}/ciclos/sanidad/tratamientos` | | `ciclo_polinizacion_dn` | — | `{url_base}/ciclos/polinizacion` | | `kilos_finca_dn` | — | `{url_base}/produccion/kilos-finca` | | `produccion_lotes_dn` | — | `{url_base}/produccion/kilos-lotes` | | `mantenimiento_dn` | — | `{url_base}/mantenimiento` | | `ciclos_cosecha_up` | `https://httpbin.org/post` | `{url_base}/ciclos/cosecha` | | `ciclos_sanidad_up` | `https://httpbin.org/post` | `{url_base}/ciclos/sanidad` | | `ciclos_polinizacion_up` | `https://httpbin.org/post` | `{url_base}/ciclos/polinizacion` | | `tiquetes_up` | `https://httpbin.org/post` | `{url_base}/tiquetes` | | `ausentismos_up` | `https://httpbin.org/post` | `{url_base}/ausentismos` | | `pluvio_upload` | `https://httpbin.org/post` | `{url_base}/pluviometria` | --- ## Preguntas frecuentes **¿Los valores numéricos (kilos, días, racimos) vienen como número o texto?** Vienen como `string` (texto libre que escribió el usuario). El ERP debe convertirlos al tipo necesario. **¿El campo `fecha` está en formato ISO?** El usuario la escribe libremente (puede ser "30/06/2026", "hoy", "30 de junio"...). Se recomienda que el ERP acepte texto y aplique parsing, o el bot puede configurarse para validar el formato antes de enviar (a coordinar). **¿Qué pasa si el ERP responde un error?** Si el ERP devuelve HTTP 4xx o 5xx, el bot muestra al usuario: *"Hubo un error al enviar los datos. Intenta nuevamente."* **¿Cómo se prueba antes de tener el ERP listo?** Los endpoints de upload actualmente apuntan a `https://httpbin.org/post`, que devuelve el body recibido. Sirve para confirmar que el bot está enviando los datos correctamente. **¿Con qué frecuencia llaman los informes?** Solo cuando el usuario lo solicita manualmente vía WhatsApp. No hay llamadas automáticas o en segundo plano.