B Life · Scrapper Analytics API

API REST que automatiza la auditoría de cobros de B Life sobre el portal de Zumalabs: lista las órdenes y valida que cada una esté correctamente cobrada.

¿Qué hace?

Expone como servicio dos capacidades sobre tu cuenta de Zumalabs:

¿Por qué funciona así?

El portal de Zumalabs no ofrece una API pública, por lo que el servicio inicia sesión y obtiene los datos de forma confiable: prefiere las APIs internas del portal (p. ej. get_product_costs para los tabuladores) y, cuando no existen, cae a un scraping calibrado del DOM con Playwright. La lógica de negocio clave —agrupar variantes de un mismo producto en una familia, sumar su volumen y exigir el mejor descuento del escalón alcanzado— se aplica sobre esos datos para reproducir exactamente la política comercial.

¿Qué logramos?

Base URL

https://scrapper.blifecompany.mx

Todas las respuestas son application/json (excepto esta página y el PDF). Las peticiones se procesan de forma secuencial: el servicio comparte una única sesión de navegador.

Autenticación

Los endpoints de datos (GET /orders y POST /validate) están protegidos con una API key. Envíala en cada petición mediante uno de estos headers:

x-api-key: TU_API_KEY
# — o —
Authorization: Bearer TU_API_KEY

Si falta o es inválida, la respuesta es 401 Unauthorized. Los endpoints /health, /api y /openapi.json son públicos.

La key se configura en el servidor con la variable de entorno API_KEY. Trátala como un secreto y envíala siempre sobre HTTPS. El servicio, a su vez, se autentica contra Zumalabs con ZUMA_EMAIL / ZUMA_PASSWORD (nunca expuestas al cliente).

Convenciones

Health

GET/health

Verifica que el servicio está arriba. No abre el navegador ni requiere sesión.

Respuesta 200
{
  "status": "ok"
}

Listar órdenes

GET/orders

Devuelve las órdenes del portal (con paginación interna ya resuelta) y permite filtrar, ordenar y paginar la respuesta. Todos los parámetros son opcionales y combinables.

ParámetroTipoDescripción
statusstringStatus derivado. Lista con coma: Pendiente,En proceso
shippingStatusstringSubstring del estado de envío original
from / todateRango de fecha (ISO, incluyente)
minTotal / maxTotalnumberRango de total
qstringBúsqueda por número de orden
sortenumdate | total | orderNumber (default date)
orderenumasc | desc (default desc)
limit / offsetintegerPaginación de la respuesta
Ejemplo · cURL
curl "https://scrapper.blifecompany.mx/orders?status=En%20proceso&minTotal=5000000&sort=total&order=desc&limit=10" \
  -H "x-api-key: TU_API_KEY"
Respuesta 200
{
  "total": 80,
  "matched": 25,
  "count": 10,
  "filters": { "status": ["En proceso"] },
  "orders": [
    {
      "orderNumber": "S10996",
      "date": "2026-06-12",
      "placedAt": "12/06/2026 16:08:16",
      "shippingStatus": "Parcialmente entregado",
      "status": "En proceso",
      "total": 7921674.8
    }
  ]
}

Validar orden

POST/validate

Inicia sesión, resuelve la orden por su número, la scrapea y valida: (1) consistencia aritmética y (2) descuento por volumen de familia contra los tabuladores de /clientes. Devuelve el reporte completo y, opcionalmente, genera un PDF con la marca B Life.

Campo (body JSON)TipoDescripción
orderNumber requeridostringNúmero (S10995) o id numérico (7192)
dryRun opcionalbooleanSi true, no persiste el reporte JSON ni envía alertas
pdf opcionalbooleanSi true, genera el PDF en reports/
Ejemplo · cURL
curl -X POST https://scrapper.blifecompany.mx/validate \
  -H "content-type: application/json" \
  -H "x-api-key: TU_API_KEY" \
  -d '{ "orderNumber": "S10995", "pdf": true }'
Respuesta · 200 correcto / 422 con discrepancias (extracto)
{
  "summary": {
    "billingCorrect": true,
    "familyPricingCorrect": false,
    "hasDifferences": true,
    "differenceCount": 25
  },
  "billing": { "orderName": "S10995", "correct": true, "checks": [ ... ] },
  "familyPricing": {
    "correct": false,
    "families": [
      { "family": "b life: pure berberine", "totalQuantity": 13230,
        "bracketMinQty": 10000, "expectedSavings": 0.36, "passed": false,
        "members": [ { "sku": "BLNBERBE180", "actualSavings": 0.22,
          "expectedUnitPrice": 160.64, "passed": false } ] }
    ]
  }
}
El código HTTP es 200 si todo está correcto y 422 si hay discrepancias (cobro incorrecto o diferencias contra la referencia). En ambos casos el cuerpo es el reporte.

Modelos

OrderSummary

CampoTipoEjemplo
orderNumberstringS10994
datedate2026-06-12
placedAtstring12/06/2026 16:09:05
shippingStatusstringSin entregar
statusstringPendiente
totalnumber5507088.4

Códigos de estado

200OK (listado, o validación correcta — devuelve el reporte)
422Validación con discrepancias (devuelve el reporte)
400Petición inválida (falta orderNumber)
401API key faltante o inválida
404Orden no encontrada o sesión inválida
502Fallo de scraping no recuperable
Formato de error
{
  "error": "ExtractionError",
  "message": "No se encontró la orden \"S99999\" en /my/orders",
  "orderNumber": "S99999"
}

OpenAPI

Especificación OpenAPI 3.0 disponible para generar clientes/SDKs e integrar en otros sistemas:

GET https://scrapper.blifecompany.mx/openapi.json

Impórtala en Postman, Insomnia, Swagger UI o un generador de SDK (openapi-generator).

✦ Implementa esta API con AI · Claude

¿Quieres integrar esta API en tu software sin leer toda la doc a mano? Copia el siguiente prompt y pégalo en Claude (o Claude Code). Incluye todo el contexto necesario para que genere el cliente/integración en el lenguaje que uses. Ajusta las dos líneas marcadas con <...>.

Prompt para Claude
Eres un ingeniero senior. Integra la "B Life · Scrapper Analytics API" en mi software.

CONTEXTO DE LA API
- Base URL: https://scrapper.blifecompany.mx
- Autenticación: API key en header "x-api-key: TU_API_KEY" (o "Authorization: Bearer TU_API_KEY")
  en /orders y /validate. Si falta -> 401. /health y /openapi.json son públicos.
- Especificación OpenAPI 3.0 (fuente de verdad): https://scrapper.blifecompany.mx/openapi.json
- Todas las respuestas son JSON. Errores: { "error", "message" } con HTTP 400/404/422/502.

ENDPOINTS
1) GET /health -> { "status": "ok" }
2) GET /orders -> listado de órdenes. Query params (todos opcionales, combinables):
   status (Pendiente|En proceso|Entregado, lista con coma), shippingStatus, from, to (YYYY-MM-DD),
   minTotal, maxTotal, q (busca por número), sort (date|total|orderNumber), order (asc|desc),
   limit, offset. Respuesta: { total, matched, count, filters, orders[] }.
   orders[]: { orderNumber, date, placedAt, shippingStatus, status, total }.
3) POST /validate  body: { "orderNumber": "S10995", "dryRun"?: bool, "pdf"?: bool }
   -> reporte de validación. HTTP 200 = correcto, 422 = con discrepancias (NO es error fatal).
   Campos clave: summary.billingCorrect, summary.familyPricingCorrect, summary.hasDifferences,
   familyPricing.families[] (family, totalQuantity, bracketMinQty, expectedSavings, passed, members[]).

TAREA
1. Genera un cliente tipado para <LENGUAJE / FRAMEWORK> con funciones listOrders(filtros) y
   validateOrder(orderNumber, opciones), con reintentos y manejo de errores (trata 422 como
   "validado con discrepancias", no como fallo).
2. Caso de uso: <DESCRIBE QUÉ QUIERES HACER, p. ej. "cada hora, listar órdenes En proceso y
   alertar en Slack las órdenes con familyPricingCorrect=false">.

Primero descarga y razona sobre https://scrapper.blifecompany.mx/openapi.json. Devuelve el código completo,
instrucciones de configuración y un ejemplo de ejecución.
Integración nativa con Claude (tool use / MCP). El mismo prompt sirve para pedirle a Claude que envuelva estos endpoints como herramientas (tool use) o como un pequeño servidor MCP, de modo que un agente pueda listar y validar órdenes por sí mismo. Apunta a https://scrapper.blifecompany.mx/openapi.json como contrato.