API da Wivo Analytics

A API da Wivo permite acessar programaticamente dados de vendas, itens de pedidos, custos associados (comissões, fretes, promoções, publicidade), margens e métricas de rentabilidade disponíveis nos relatórios da plataforma.

Por onde começar? Se você vai integrar pela primeira vez, leia as seções 1 a 6 em ordem: elas levam você desde habilitar a API até deixar seus dados sincronizados. As seções 7 a 11 são a referência técnica que você vai consultar de vez em quando (parâmetros, campos, limites).

1. Principais casos de uso

  1. Integrar dados da Wivo em data warehouses, ERPs, sistemas contábeis ou ferramentas internas
  2. Automatizar relatórios e painéis personalizados sem exportações manuais de arquivos

2. Dados disponíveis

A API entrega informação em nível de item de pedido, que inclui:

  • Detalhe do pedido (ID, data de compra, SKUs, tipo de envio, status de pedido e pagamento)
  • Custos do pedido (comissões, frete, logística)
  • Custos adicionais (armazenamento fulfillment, publicidade)
  • Métricas derivadas (rentabilidade, percentual de rentabilidade)

3. Habilitar a API

  1. Acesse sua conta da Wivo com credenciais de administrador
  2. Vá para “Integração API” no menu superior direito
  3. Clique em “Solicitar habilitação da API”
  4. Agende uma reunião com um representante da Wivo para a ativação
  5. Receba sua API Key pessoal e confidencial

4. Autenticação

Inclua sua API Key no header HTTP de cada requisição:

Ocp-Apim-Subscription-Key: SUA_API_KEY

Chaves inválidas ou ausentes retornam HTTP 401 Unauthorized. Se a sua conta não tiver o acesso à API de dados habilitado, ou a assinatura tiver sido revogada, retorna HTTP 403 Forbidden.

5. Sua primeira requisição

Com a sua API Key pronta, faça esta requisição para confirmar que tudo funciona. Ela traz os itens de pedidos de uma faixa de datas:

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

A resposta é um JSON com duas partes:

  • data — o array de itens de pedido (cada um com suas vendas, custos e rentabilidade). Veja o detalhe dos campos na seção 8.
  • meta — informação de paginação. Observe totalPages: indica quantas páginas é preciso percorrer para trazer toda a faixa.

Com isso você já pode explorar os dados. Para uma integração de verdade, continue na seção 6 (como manter seus dados sincronizados) e use as seções 7 a 11 como referência do detalhe de cada parâmetro e campo.

6. Como sincronizar seus dados: fluxo histórico vs. fluxo regular

Para uma integração real você terá dois fluxos: uma carga histórica (uma única vez, para trazer todo o passado) e um fluxo regular (recorrente, para se manter sincronizado).

Modelo mental — por que apagar e inserir (delete + insert): Um pedido não é imutável. Após a compra, ele pode mudar de status, ajustar custos, receber reembolsos ou ser cancelado. Por isso, cada vez que um pedido aparece na resposta, apague todos os seus itens no seu banco e insira-os completos de novo. Assim sua cópia sempre reflete o último estado da Wivo, sem duplicados nem dados antigos. O campo para agrupar os itens de um mesmo pedido é Orden.

6.1. Carga histórica (backfill inicial)

Objetivo: trazer todo o histórico disponível, uma única vez.

Use date=purchase_date e pagine até esgotar a faixa. O campo meta.totalPages da resposta (ver seção 8) indica quantas páginas existem:

page = 1
total_pages = 1                      # é atualizado com a primeira resposta
while page <= total_pages:
    resp = GET("/data", params={
        "date": "purchase_date",
        "from": "2020-01-01",
        "to":   "2025-01-31",        # hoje
        "page": page,
        "limit": 100,
    })
    salvar_com_delete_insert(resp["data"])   # apagar itens de cada Orden e reinserir
    total_pages = resp["meta"]["totalPages"]
    page += 1

# Guarde o maior "Fecha de actualización" (updated_at) que você tiver visto:
# é o ponto de partida do fluxo regular.

Respeite o rate limit (5 req/min, ver seção 10): adicione uma pausa entre páginas e retentativas com backoff exponencial diante de um HTTP 429.

6.2. Fluxo regular (incremental, por hora ou por dia)

Objetivo: manter sua cópia sincronizada trazendo apenas o que mudou.

Use date=updated_at a partir da última data que você processou. Isso traz pedidos novos e atualizações (mudanças de status, ajustes de custo, cancelamentos, reembolsos):

last_synced = "2025-01-15T09:55:00"   # ← último updated_at processado, MENOS a janela de segurança

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

A janela se aplica à data de atualização: a resposta traz os subpedidos atualizados no intervalo, mesmo que tenham sido comprados antes. Um pedido comprado três meses atrás que hoje muda de status aparece na janela de hoje.

O alcance cobre as compras dos últimos 120 dias e vem declarado em cada resposta (ver seção 11).

Janela de segurança (recomendado): subtraia 5–10 min do seu último updated_at antes de pedir de novo. Se o último processado foi 2025-01-15T10:00:00, peça a partir de 2025-01-15T09:55:00. Isso evita perder mudanças por desvios de relógio ou latência. Como você reinsere por pedido completo, trazer um pedido de novo não gera duplicados.

Escolha janelas curtas. Uma janela de vários dias pode retornar dezenas de páginas. Com o rate limit de 5 req/min (ver seção 10), sincronizar por hora é mais rápido e leve do que por dia.

Limite de 7 dias com updated_at: uma requisição não pode cobrir mais de 7 dias (ver seção 7.2). Se o seu processo ficou parado por mais de uma semana, avance em janelas de ≤7 dias até alcançar o presente.

7. Referência: endpoint e parâmetros

7.1. Endpoint

  • GET /data — Retorna pedidos e itens de custos com todo o detalhe.

7.2. Parâmetros de GET /data

  • date (purchase_date ou updated_at): Você deve escolher um destes parâmetros (obrigatório)
  • from: obrigatório, ISO 8601. Aceita 2025-01-31 ou 2025-01-31T09:55:00
  • to: opcional, ISO 8601. Aceita 2025-02-01 ou 2025-02-01T18:30:00
  • item_type: opcional, orders ou publications. Filtra o tipo de item
  • page: opcional
  • limit: opcional, tamanho de página. Padrão 100, máximo 100
  • categories: opcional, lista separada por vírgulas: income, costs, reimbursement. Adiciona à resposta as medidas dessas categorias e o seu total (ver seção 9). Se for omitido, retorna apenas o conjunto base

Hora em from e to: se você enviar hora, ela é respeitada. Se enviar apenas a data, from é completado às 00:00:00 e to às 23:59:59 desse dia. O fuso em que são interpretados depende do campo que você filtra (ver seção 11).

Limite de intervalo: com date=updated_at o intervalo não pode exceder 7 dias. Com purchase_date, o máximo depende do seu plano. Um parâmetro inválido (data, intervalo excedido ou item_type inválido) retorna HTTP 400 Bad Request.

Exemplos:

Com 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: SUA_API_KEY_AQUI"

Com updated_at:

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

8. Estrutura de resposta de GET /data

Exemplo 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.000Z",
      "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.000Z",
      "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"
    }
    // ... aqui você pode continuar adicionando mais itens com os mesmos 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"
}

O objeto meta dá tudo o que você precisa para paginar: page (página atual), totalPages (total de páginas do intervalo) e totalRows (total de itens). Percorra de page=1 até totalPages para trazer o intervalo completo.

Ele também traz window e fields, que declaram o fuso horário da janela e de cada campo de data (ver seção 11):

"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,
  "window": { "field": "purchase_date", "timezone": "local" },
  "fields": {
    "Fecha de compra": { "type": "datetime", "timezone": "local" },
    "Fecha de actualización": { "type": "datetime", "timezone": "UTC" }
  }
}

9. Categorias de medidas (categories)

Por padrão, cada item de data traz um conjunto base de 7 medidas. São as que você vê no exemplo da seção 8:

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

O parâmetro categories adiciona colunas extras a cada item de data, com o detalhamento por trás desses totais. Você pede uma ou mais categorias separadas por vírgula (income, costs, reimbursement). Cada categoria adiciona suas medidas mais um campo de total.

As colunas são identificadas pelo seu nome exato (o mesmo que aparece como chave no JSON). As chaves são em espanhol, independentemente do idioma. Se você pedir várias categorias e elas compartilharem alguma medida, a coluna aparece uma única vez (não se duplica). Os totais Ventas e Costo de Marketplace já vêm no conjunto base; as categorias adicionam o detalhamento.

income — Receitas do pedido

Coluna
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 da categoria

costs — Custos do marketplace

Reflete a análise de custos da plataforma, agrupada por seção. O total de cada seção está em negrito, e Costo de Marketplace é o total geral (soma de todas as seções).

Comissões: Cobro de Comisiones, Reembolso de Comisiones, Costo de Comisiones

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

Publicidade: Cobro por publicidad, Reembolso por publicidad, Costos por publicidad

Armazenamento 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

Outros custos: 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

Total geral: Costo de Marketplace

reimbursement — Reembolsos de cobranças

Coluna
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 da categoria

Exemplo

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: SUA_API_KEY_AQUI"

Cada item de data chega com o conjunto base mais as colunas das categorias pedidas (em negrito as que aparecem apenas por causa de 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"
}

Uma categoria inválida retorna HTTP 400 Bad Request.

10. Limites de uso (Rate limits)

  • 5 requisições por minuto por conta
  • 5.000 requisições por dia (recomendado)
  • Exceder os limites retorna HTTP 429 Too Many Requests

Como boa prática, implemente retentativas com backoff exponencial e agrupe a lógica para aproveitar ao máximo cada requisição.

11. Datas e fusos horários

A resposta traz dois campos de data, e cada um vem em um fuso diferente. Isso é importante para qualquer cálculo ou cruzamento com suas próprias fontes.

CampoFusoFormato
Fecha de actualizaciónUTC2026-08-14T16:00:42.286Z — com designador Z e milissegundos
Fecha de compraHora local do canal de venda2026-08-14T08:12:59.000 — sem designador de fuso

Fecha de actualización

Vem sempre em UTC, com o Z e com milissegundos. É o mesmo valor independentemente do campo pelo qual você filtra, então você pode interpretá-la diretamente como um instante.

Marca quando a Wivo atualizou esse registro por último, e é o campo usado como cursor do fluxo incremental da seção 6.2.

Fecha de compra

Vem na hora local do canal de venda, sem designador de fuso. Não a interprete como UTC: a maioria dos parsers assume UTC quando falta o Z, e isso desloca a data em várias horas.

Como o fuso depende do canal, dois pedidos comprados no mesmo instante em canais de países diferentes trazem relógios diferentes neste campo. Se você precisa comparar instantes ou cruzar com fontes em UTC, use Fecha de actualización.

Fuso de from e to

Eles são interpretados no mesmo fuso do campo que você está filtrando, e meta.window informa isso em cada resposta:

FiltroFuso de from e to
date=updated_atUTC
date=purchase_dateHora local do canal, igual ao campo

Com date=updated_at, o valor de Fecha de actualización que você recebe pode ser reenviado como from na requisição seguinte, sem conversão.

Alcance da busca por data de atualização

Com date=updated_at, a resposta inclui os subpedidos cuja data de compra esteja dentro dos 120 dias anteriores ao início do intervalo consultado.

Cada resposta declara esse limite em meta.window.purchaseDateFrom:

"window": {
  "field": "updated_at",
  "timezone": "UTC",
  "purchaseDateFrom": "2026-04-16T00:00:00"
}

Para consultar compras anteriores a esse limite, use date=purchase_date com o intervalo que precisar.

Declaração na resposta

O meta.fields declara o fuso de cada campo de data em cada resposta, com as mesmas chaves que você vê em data. Se a sua integração precisa verificar o formato antes de interpretar, leia dali em vez de assumir.