API de Wivo Analytics

La API de Wivo te permite acceder programáticamente a datos de ventas, ítems de órdenes, costos asociados (comisiones, envíos, promociones, publicidad), márgenes y métricas de rentabilidad disponibles en los reportes de la plataforma.

¿Por dónde empezar? Si vas a integrar por primera vez, leé las secciones 1 a 6 en orden: te llevan desde habilitar la API hasta dejar tus datos sincronizados. Las secciones 7 a 10 son la referencia técnica que vas a consultar de a ratos (parámetros, campos, límites).

1. Casos de uso principales

  1. Integrar datos de Wivo en data warehouses, ERPs, sistemas contables o herramientas internas
  2. Automatizar reportes y dashboards personalizados sin exportaciones manuales de archivos

2. Datos disponibles

La API entrega información a nivel de ítem de orden, que incluye:

  • Detalle de la orden (ID, fecha de compra, SKUs, tipo de envío, estado de orden y pago)
  • Costos de la orden (comisiones, envío, logística)
  • Costos adicionales (almacenamiento fulfillment, publicidad)
  • Métricas derivadas (rentabilidad, porcentaje de rentabilidad)

3. Habilitar la API

  1. Accede a tu cuenta de Wivo con credenciales de administrador
  2. Ve a “Integración API” en el menú superior derecho
  3. Haz clic en “Solicitar habilitación de API”
  4. Agenda una reunión con un representante de Wivo para la activación
  5. Recibe tu API Key personal y confidencial

4. Autenticación

Incluye tu API Key en el header HTTP de cada petición:

Ocp-Apim-Subscription-Key: TU_API_KEY

Las claves inválidas o ausentes retornan HTTP 401 Unauthorized. Si tu cuenta no tiene habilitado el acceso a la API de datos, o la suscripción fue revocada, retorna HTTP 403 Forbidden.

5. Tu primera petición

Con tu API Key lista, hacé esta petición para confirmar que todo funciona. Trae los ítems de órdenes de un rango de fechas:

curl "https://api.wivoanalytics.com/data?date=purchase_date&from=2025-01-01&to=2025-01-31&page=1" \
  -H "Ocp-Apim-Subscription-Key: TU_API_KEY_AQUI"

La respuesta es un JSON con dos partes:

  • data — el array de ítems de orden (cada uno con sus ventas, costos y rentabilidad). Ver el detalle de los campos en la sección 8.
  • meta — información de paginación. Fijate en totalPages: te dice cuántas páginas hay que recorrer para traer todo el rango.

Con esto ya podés explorar los datos. Para una integración de verdad, seguí con la sección 6 (cómo mantener tus datos sincronizados) y usá las secciones 7 a 10 como referencia del detalle de cada parámetro y campo.

6. Cómo sincronizar tus datos: flujo histórico vs. flujo regular

Para una integración real vas a tener dos flujos: una carga histórica (una sola vez, para traer todo el pasado) y un flujo regular (recurrente, para mantenerte sincronizado).

Modelo mental — por qué borrar e insertar (delete + insert): Una orden no es inmutable. Después de la compra puede cambiar de estado, ajustar costos, recibir reembolsos o cancelarse. Por eso, cada vez que una orden aparece en la respuesta, borrá todos sus ítems en tu base y volvé a insertarlos completos. Así tu copia siempre refleja el último estado de Wivo, sin duplicados ni datos viejos. El campo para agrupar los ítems de una misma orden es Orden.

6.1. Carga histórica (backfill inicial)

Objetivo: traer toda la historia disponible, una sola vez.

Usá date=purchase_date y paginá hasta agotar el rango. El campo meta.totalPages de la respuesta (ver sección 8) te dice cuántas páginas hay:

page = 1
total_pages = 1                      # se actualiza con la primera respuesta
while page <= total_pages:
    resp = GET("/data", params={
        "date": "purchase_date",
        "from": "2020-01-01",
        "to":   "2025-01-31",        # hoy
        "page": page,
        "limit": 100,
    })
    guardar_con_delete_insert(resp["data"])   # borrar ítems de cada Orden y reinsertar
    total_pages = resp["meta"]["totalPages"]
    page += 1

# Guardá el mayor "Fecha de actualización" (updated_at) que hayas visto:
# es el punto de partida del flujo regular.

Respetá el rate limit (5 req/min, ver sección 10): agregá una pausa entre páginas y reintentos con backoff exponencial ante un HTTP 429.

6.2. Flujo regular (incremental, por hora o por día)

Objetivo: mantener tu copia sincronizada trayendo solo lo que cambió.

Usá date=updated_at desde la última fecha que procesaste. Esto trae órdenes nuevas y actualizaciones (cambios de estado, ajustes de costo, cancelaciones, reembolsos):

last_synced = "2025-01-15T09:55:00"   # ← último updated_at procesado, MENOS la ventana de seguridad

page = 1
total_pages = 1
while page <= total_pages:
    resp = GET("/data", params={
        "date": "updated_at",
        "from": last_synced,
        "page": page,
        "limit": 100,
    })
    guardar_con_delete_insert(resp["data"])
    total_pages = resp["meta"]["totalPages"]
    page += 1

Ventana de seguridad (recomendado): restá 5–10 min a tu último updated_at antes de pedir de nuevo. Si lo último procesado fue 2025-01-15T10:00:00, pedí desde 2025-01-15T09:55:00. Esto evita perder cambios por desfases de reloj o latencia. Como reinsertás por orden completa, volver a traer una orden no genera duplicados.

Límite de 7 días con updated_at: un request no puede cubrir más de 7 días (ver sección 7.2). Si tu proceso estuvo caído más de una semana, avanzá en ventanas de ≤7 días hasta alcanzar el presente.

7. Referencia: endpoint y parámetros

7.1. Endpoint

  • GET /data — Devuelve órdenes e ítems de costos con todo su detalle.

7.2. Parámetros de GET /data

  • date (purchase_date o updated_at): Debes escoger uno de estos parámetros (obligatorio)
  • from: obligatorio, ISO 8601, ej: 2025-01-31
  • to: opcional, ISO 8601, ej: 2025-02-01
  • item_type: opcional, orders o publications. Filtra el tipo de ítem
  • page: opcional
  • limit: opcional, tamaño de página. Default 100, máximo 100
  • categories: opcional, lista separada por comas: income, costs, reimbursement. Agrega a la respuesta las medidas de esas categorías y su total (ver sección 9). Si se omite, se devuelve solo el set base

Límite de rango: con date=updated_at el rango no puede exceder 7 días. Con purchase_date, el máximo depende de tu plan. Un parámetro inválido (fecha, rango excedido o item_type no válido) retorna HTTP 400 Bad Request.

Ejemplos:

Con purchase_date:

curl "https://api.wivoanalytics.com/data?date=purchase_date&from=2025-01-01&to=2025-01-31&page=1" \
  -H "Ocp-Apim-Subscription-Key: TU_API_KEY_AQUI"

Con updated_at:

curl "https://api.wivoanalytics.com/data?date=updated_at&from=2025-01-01T20:55:00" \
  -H "Ocp-Apim-Subscription-Key: TU_API_KEY_AQUI"

8. Estructura de respuesta de GET /data

Ejemplo simplificado:

{
  "data": [
    {
      "Canal": "Marketplace A",
      "Cuenta": "Cuenta Demo 1",
      "Orden": "1000000000000001",
      "Nro. suborden": "1000000000000001",
      "Nro. Paquete": "1000000000000001",
      "N° de Liquidación": "1000000000000001",
      "SKU Producto": "SKU-DEMO-001",
      "SKU Marketplace": "9000000000001",
      "Producto": "Producto Demostración 1 - Talla: L",
      "Variante": "Talla: L",
      "SKU Variante": "SKU-DEMO-001",
      "Fecha de actualización": "2024-01-11T06:26:29.000",
      "Estado de Orden": "Regular",
      "Estado de Pago": "Pagado",
      "Estado de Despacho": "Entregado",
      "Tipo de Despacho": "No Fulfillment",
      "Fecha de compra": "2024-01-09T23:56:56.000",
      "Ventas": "7500",
      "Unidades": "1",
      "Costo de Marketplace": "1500.00",
      "Rentabilidad Marketplace": "6000.00",
      "% Rentabilidad Marketplace": "80.00",
      "Costo Envío": "1000",
      "Costo de Comisiones": "500"
    },
    {
      "Canal": "Marketplace A",
      "Cuenta": "Cuenta Demo 1",
      "Orden": "1000000000000002",
      "Nro. suborden": "1000000000000003",
      "Nro. Paquete": "1000000000000002",
      "N° de Liquidación": "1000000000000002",
      "SKU Producto": "SKU-DEMO-002",
      "SKU Marketplace": "9000000000002",
      "Producto": "Producto Demostración 2 - Talla: L Tamaño: 10.2",
      "Variante": "Color: Azul, Tamaño: 10.2",
      "SKU Variante": "SKU-DEMO-002",
      "Fecha de actualización": "2024-01-11T06:29:13.000",
      "Estado de Orden": "Regular",
      "Estado de Pago": "Pagado",
      "Estado de Despacho": "Entregado",
      "Tipo de Despacho": "Fulfillment",
      "Fecha de compra": "2024-01-09T23:56:43.000",
      "Ventas": "12000",
      "Unidades": "1",
      "Costo de Marketplace": "4000.00",
      "Rentabilidad Marketplace": "8000.00",
      "% Rentabilidad Marketplace": "66.67",
      "Costo Envío": "2000",
      "Costo de Comisiones": "2000"
    }
    // ... aquí podrías seguir agregando más items con los mismos campos
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "count": 100,
    "from": "2024-01-09T00:00:00",
    "to": "2024-01-09T23:59:59",
    "date": "purchase_date",
    "totalRows": 3282,
    "totalPages": 33
  },
  "correlation_id": "00000000-0000-4000-8000-000000000001"
}

El objeto meta te da todo lo necesario para paginar: page (página actual), totalPages (total de páginas del rango) y totalRows (total de ítems). Recorré desde page=1 hasta totalPages para traer el rango completo.

9. Categorías de medidas (categories)

Por defecto, cada ítem de data trae un set base de 7 medidas. Son las que ves en el ejemplo de la sección 8:

Ventas, Unidades, Costo de Marketplace, Rentabilidad Marketplace, % Rentabilidad Marketplace, Costo Envío, Costo de Comisiones.

El parámetro categories agrega columnas adicionales a cada ítem de data, con el desglose detrás de esos totales. Pedís una o más categorías separadas por coma (income, costs, reimbursement). Cada categoría agrega sus medidas más un campo de total.

Las columnas se identifican por su nombre exacto (el mismo que aparece como clave en el JSON). Si pedís varias categorías y comparten alguna medida, la columna aparece una sola vez (no se duplica). Los totales Ventas y Costo de Marketplace ya vienen en el set base; las categorías agregan su desglose.

income — Ingresos de la orden

Columna
Ventas
Despacho pagado por comprador
Ingreso por Envío Flex
Ingreso de Compensación por Daños
Ingreso por promoción
Ingresos sin categorizar
Ingreso Totaltotal de la categoría

costs — Costos del marketplace

Refleja el análisis de costos de la plataforma, agrupado por sección. El total de cada sección está en negrita, y Costo de Marketplace es el gran total (suma de todas las secciones).

Comisiones: Cobro de Comisiones, Reembolso de Comisiones, Costo de Comisiones

Envío: Despacho pagado por comprador, Cobro Envío Flex, Ingreso por Envío Flex, Reembolso de envío, Cobro de Envío, Costo Envío

Publicidad: Cobro por publicidad, Reembolso por publicidad, Costos por publicidad

Almacenamiento Fulfillment: Cobro por Costo Logístico, Reembolso de Costo Logístico, Cobro por Servicio Almacenamiento, Cobro por Almacenamiento Prolongado, Cobro por Descarte de Stock, Reembolso por servicio almacenamiento, Reembolso por descarte de stock, Reembolso por almacenamiento prolongado, Costos de Almacenamiento Fulfillment

Otros costos: Cobro de Ajuste sobre la Comisión, Reembolso de Ajuste sobre la Comisión, Cobro de Penalizacion por Cancelación, Devolución de Penalizacion por Cancelación, Cobro Logística Inversa, Reembolso Logística Inversa, Cobro de Penalizacion por Daños, Ingreso de Compensación por Daños, Reembolso de Ajuste sobre Venta, Ingreso por promoción, Cobros sin categorizar, Ingresos sin categorizar, Reembolsos sin categorizar, Cobro de Impuestos, Reembolso de Impuestos, Otros costos

Gran total: Costo de Marketplace

reimbursement — Reembolsos de cargos

Columna
Reembolso de Ajuste sobre la Comisión
Devolución de Penalizacion por Cancelación
Reembolso Logística Inversa
Reembolso de Ajuste sobre Venta
Reembolso de Comisiones
Reembolso de envío
Reembolso de Costo Logístico
Reembolso por publicidad
Reembolsos sin categorizar
Reembolso por servicio almacenamiento
Reembolso por descarte de stock
Reembolso por almacenamiento prolongado
Reembolso de Impuestos
Reembolso Totaltotal de la categoría

Ejemplo

curl "https://api.wivoanalytics.com/data?date=purchase_date&from=2025-01-01&to=2025-01-31&categories=income,costs" \
  -H "Ocp-Apim-Subscription-Key: TU_API_KEY_AQUI"

Cada ítem de data llega con el set base más las columnas de las categorías pedidas (en negrita las que aparecen solo por categories=income,costs):

{
  "Orden": "1000000000000001",
  "Ventas": "7500",
  "Unidades": "1",
  "Costo de Marketplace": "1500.00",
  "Rentabilidad Marketplace": "6000.00",
  "Ingreso Total": "7500.00",
  "Cobro de Comisiones": "500",
  "Costo de Comisiones": "500",
  "Cobro de Envío": "1000",
  "Costo Envío": "1000"
}

Una categoría no válida retorna HTTP 400 Bad Request.

10. Límites de uso (Rate limits)

  • 5 peticiones por minuto por cuenta
  • 5.000 peticiones por día (recomendado)
  • Superar los límites retorna HTTP 429 Too Many Requests

Como buenas prácticas, implementa reintentos con backoff exponencial y agrupa la lógica para aprovechar al máximo cada petición.