Complete endpoint specification for the ERP team: - 10 GET (download) endpoints returning PDF/Excel files - 6 POST (upload) endpoints receiving WhatsApp form data - Auth headers, request/response schemas, and endpoint_key mapping table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
14 KiB
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):
[
{ "id": "finca_001", "label": "Finca La Palma" },
{ "id": "finca_002", "label": "Finca El Diamante" },
{ "id": "finca_003", "label": "Finca Los Almendros" }
]
El campo
ides el valor que el bot usará internamente;labeles 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_desdeyfecha_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):
{
"status": "ok",
"message": "Registro guardado correctamente"
}
Si hay error (400/500):
{
"status": "error",
"message": "Descripción del error"
}
11. ⚠️ Registrar ciclo cosecha
POST {url_base}/ciclos/cosecha
Body 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:
{
"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:
{
"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:
{
"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:
{
"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:
{
"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.