Carga de custos de produtos pela API
A Wivo permite atualizar os custos dos seus produtos de forma programática por meio de um arquivo CSV enviado à API. Os custos são processados em segundo plano e você receberá uma notificação por e-mail quando o processo terminar.
Esta funcionalidade está disponível para contas com plano Pro.
Para que serve?
- Sincronizar custos automaticamente a partir do seu ERP, data warehouse ou sistema contábil
- Programar atualizações periódicas (diárias, semanais) sem intervenção manual
- Atualizar custos de milhares de produtos em uma única operação
Requisitos
- Conta Wivo com plano Pro
- API Key ativa (obtém-se a partir da seção Integrações na plataforma)
Base URL
https://api.wivoanalytics.com
Autenticação
Todas as solicitações devem incluir a API Key no seguinte header HTTP:
Ocp-Apim-Subscription-Key: SUA_API_KEY_AQUI
Solicitações sem API Key ou com chave inválida recebem 401 Unauthorized.
Importante: Sua API Key é um segredo. Não a compartilhe, não a inclua em código-fonte público nem a exponha em logs. Armazene-a em variáveis de ambiente ou em um gerenciador de segredos.
Como obter sua API Key?
- Entrar na Wivo — Acesse sua conta com seu usuário administrador.
- Ir para Integrações — No menu do canto superior direito, clique em “Integração com API”.
- Solicitar habilitação — Clique em “Solicitar habilitar API” e agende uma reunião com a equipe da Wivo para ativar seu acesso.
- Obter sua chave — Uma vez habilitada, sua API Key será exibida. É pessoal, secreta e está associada à sua conta.
Endpoints
| Método | Endpoint | Descrição |
|---|---|---|
POST | /costs/fill/csv | Carregar arquivo CSV com custos |
GET | /costs/fill-status | Consultar se há uma carga em curso |
GET | /costs/fill-history | Consultar histórico de cargas (últimos 7 dias) |
POST /costs/fill/csv
Content-Type: multipart/form-data
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
file | File | Sim | Arquivo CSV (máximo 10 MB) |
email | String | Sim | E-mail onde você receberá o resultado da carga |
username | String | Sim | Nome do usuário ou sistema que realiza a carga |
fromDate | String | Não | Data a partir da qual aplicar custos (YYYY-MM-DD). Se não for enviada, aplicam-se desde o primeiro dia do mês de 2 anos atrás |
Exemplos de código
cURL:
curl -X POST "https://api.wivoanalytics.com/costs/fill/csv" \
-H "Ocp-Apim-Subscription-Key: SUA_API_KEY_AQUI" \
-F "file=@costos.csv" \
-F "email=usuario@minhaempresa.com" \
-F "username=Pipeline de Custos" \
-F "fromDate=2024-01-01"
Python (requests):
import requests
url = "https://api.wivoanalytics.com/costs/fill/csv"
headers = {"Ocp-Apim-Subscription-Key": "SUA_API_KEY_AQUI"}
with open("costos.csv", "rb") as f:
files = {"file": ("costos.csv", f, "text/csv")}
data = {
"email": "usuario@minhaempresa.com",
"username": "Pipeline de Custos",
"fromDate": "2024-01-01",
}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.status_code) # 202
print(response.json()) # {"processId": "a1b2c3d4-..."}
Node.js (axios):
const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");
const form = new FormData();
form.append("file", fs.createReadStream("costos.csv"));
form.append("email", "usuario@minhaempresa.com");
form.append("username", "Pipeline de Custos");
form.append("fromDate", "2024-01-01");
const response = await axios.post(
"https://api.wivoanalytics.com/costs/fill/csv",
form,
{ headers: { "Ocp-Apim-Subscription-Key": "SUA_API_KEY_AQUI", ...form.getHeaders() } }
);
console.log(response.data); // { processId: "a1b2c3d4-..." }
Resposta bem-sucedida — 202 Accepted
{ "processId": "a1b2c3d4-e5f6-7890-abcd-ef3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f12347890" }
O
processIdé um identificador de referência para sua carga. Você pode citá-lo ao contatar o suporte. Não é necessário para consultar o status — a API o resolve automaticamente a partir da sua API Key.
Respostas do servidor
| Código | Significado | Tentar novamente |
|---|---|---|
202 | Arquivo recebido, processamento iniciado | Não |
400 | Arquivo não é CSV ou dados inválidos | Não |
401 | API Key ausente ou inválida | Não |
403 | Plano Pro requerido para este recurso | Não |
409 | Já há uma carga em curso | Sim |
429 | Limite de solicitações excedido | Sim |
500 | Erro interno | Sim |
400 Bad Request:
{ "success": false, "error": "Este endpoint solo acepta archivos CSV" }
401 Unauthorized:
{ "success": false, "error": "Authentication required" }
409 Conflict:
{ "message": "En estos momentos estamos procesando tu planilla. Por favor, espere a que finalice antes de subir una nueva planilla." }
500 Internal Server Error:
{ "message": "Error al subir el archivo" }
GET /costs/fill-status
Consulta se sua conta tem uma carga de custos em curso. Só pode haver uma carga ativa por vez.
cURL:
curl "https://api.wivoanalytics.com/costs/fill-status" \
-H "Ocp-Apim-Subscription-Key: SUA_API_KEY_AQUI"
Com processo ativo:
{ "process": true }
Sem processo ativo (sua carga já terminou):
{ "process": null }
Se você receber
null, sua carga já terminou. Consulte o histórico para ver o resultado, ou verifique seu e-mail.
GET /costs/fill-history
Mostra suas cargas de custos dos últimos 7 dias com seu resultado.
cURL:
curl "https://api.wivoanalytics.com/costs/fill-history" \
-H "Ocp-Apim-Subscription-Key: SUA_API_KEY_AQUI"
Resposta:
{
"process": [
{
"processId": "a1b2c3d4-...",
"status": "success",
"title": "Planilla procesada correctamente",
"message": "La planilla de productos subida por Pipeline de Costos se ha cargado exitosamente.",
"relativeTime": "hace 2 horas"
}
]
}
Valores possíveis de status: success, failed, in_progress.
Especificação do arquivo CSV
| Propriedade | Valor |
|---|---|
| Codificação | UTF-8 (com ou sem BOM) |
| Separador | Vírgula (,) |
| Delimitador de texto | Aspas duplas (") |
| Fim de linha | CRLF ou LF |
| Primeira linha | Headers |
| Tamanho máximo | 10 MB |
Colunas obrigatórias
Se faltar alguma destas colunas, o arquivo inteiro será rejeitado:
| Coluna | Tipo | Descrição | Exemplo |
|---|---|---|---|
ID Cuenta | Texto | Identificador da conta na Wivo (UUID). Você o obtém do Cadastro de produtos ou da planilha para download | 3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234 |
ID Producto | Texto | Identificador do produto no marketplace | MLB001 |
Costo de producto (con IVA) | Numérico | Custo unitário com IVA | 1500.50 |
Os nomes das colunas são sensíveis a maiúsculas e acentos. A ordem não importa.
Não construa os identificadores manualmente.
ID CuentaeID Productodevem vir do Cadastro de produtos ou da planilha para download. Se você enviar uma combinação que não existe na Wivo, a carga não falha: cria um produto novo que não corresponde a nenhum anúncio real.
Colunas opcionais
Você pode incluir colunas adicionais para enriquecer a informação: Marketplace, Cuenta, SKU Producto, Nombre Producto, Producto Interno, SKU Producto Interno, Marca Interna e Categoría Interna. Se não forem incluídas, recebem valores padrão.
Nomes alternativos (legacy)
Para compatibilidade com planilhas antigas, aceitam-se:
ID Productequivale aID ProductoCostoequivale aCosto de producto (con IVA)
Formato do campo custo
| Você escreve | É interpretado como |
|---|---|
1500 | 1500.00 |
1500.50 | 1500.50 |
1500,50 | 1500.50 |
1.500,50 | 1500.50 |
Faixa válida: -99,999,999.99 a 99,999,999.99. Valores fora da faixa ou inválidos são armazenados como vazio.
Exemplos de arquivo CSV
Arquivo completo (todas as colunas):
Marketplace,Cuenta,ID Cuenta,SKU Producto,Nombre Producto,ID Producto,Costo de producto (con IVA),Producto Interno,SKU Producto Interno,Marca Interna,Categoría Interna
mercadolibre,Mi Tienda,3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234,SKU-001,Camiseta Básica,MLB001,1500.50,Camiseta Genérica,INT-001,Nike,Ropa
mercadolibre,Mi Tienda,3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234,SKU-002,"Pantalón Cargo, modelo 2024",MLB002,3200,Pantalón Genérico,INT-002,Adidas,Ropa
mercadolibre,Mi Tienda,3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234,SKU-003,Zapatillas Running,MLB003,8500.00,Zapatillas Genéricas,INT-003,Puma,Calzado
Arquivo mínimo (apenas colunas obrigatórias):
ID Cuenta,ID Producto,Costo de producto (con IVA)
3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234,MLB001,1500.50
3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234,MLB002,3200
3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234,MLB003,8500.00
Geração do CSV por código
Python (pandas):
import pandas as pd
df = pd.DataFrame({
"ID Cuenta": ["3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234", "3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234"],
"ID Producto": ["MLB001", "MLB002"],
"Costo de producto (con IVA)": [1500.50, 3200.00],
})
df.to_csv("costos.csv", index=False, encoding="utf-8")
Node.js:
const { stringify } = require("csv-stringify/sync");
const fs = require("fs");
const data = [
["ID Cuenta", "ID Producto", "Costo de producto (con IVA)"],
["3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234", "MLB001", "1500.50"],
["3f2b1c8e-9a4d-4c2f-b7e1-5d6a8c0f1234", "MLB002", "3200.00"],
];
fs.writeFileSync("costos.csv", stringify(data), "utf-8");
Retentativas automáticas
Para os códigos 409, 429 e 500, use backoff exponencial:
| Parâmetro | Valor |
|---|---|
| Máximo de retentativas | 5 |
| Espera inicial | 30 segundos |
| Multiplicador | 2× |
| Espera máxima | 10 minutos |
| Tentativa | Espera |
|---|---|
| 1 | 30 segundos |
| 2 | 1 minuto |
| 3 | 2 minutos |
| 4 | 4 minutos |
| 5 | 8 minutos |
Para erros 409, consulte GET /costs/fill-status antes de tentar novamente para verificar se há um processo ativo.
Exemplo Python com retentativas:
import time, random, requests
API_KEY = "SUA_API_KEY_AQUI"
API_URL = "https://api.wivoanalytics.com/costs/fill/csv"
MAX_RETRIES = 5
def upload_costs(csv_path, form_data):
headers = {"Ocp-Apim-Subscription-Key": API_KEY}
for attempt in range(1, MAX_RETRIES + 1):
with open(csv_path, "rb") as f:
files = {"file": ("costos.csv", f, "text/csv")}
response = requests.post(API_URL, headers=headers, files=files, data=form_data)
if response.status_code == 202:
return response.json()
if response.status_code in (400, 401):
raise Exception(f"Error {response.status_code}: {response.json()}")
if response.status_code in (409, 429, 500):
delay = min(30 * (2 ** (attempt - 1)), 600)
time.sleep(delay + random.uniform(-5, 5))
raise Exception("Foi excedido o número máximo de retentativas")
Tempos de processamento
| Produtos | Tempo aproximado |
|---|---|
| ~500 | Segundos |
| ~2.000 | 1 a 2 minutos |
| ~10.000 | 5 a 10 minutos |
Regras de negócio
- Um processo por vez — Só pode haver uma carga ativa por conta. Se você enviar um arquivo enquanto outro está sendo processado, receberá um erro
409. - Linhas incompletas — As linhas sem
ID ProductoouID Cuentasão ignoradas; o restante é processado normalmente. - Custos inválidos — Valores vazios, inválidos ou fora da faixa são armazenados como vazio (não rejeitam o arquivo).
- Processamento em lotes — Os produtos são processados em grupos de 500.
- Identificação por nome — As colunas são identificadas por nome, não por posição.
Perguntas frequentes
Posso enviar apenas as 3 colunas obrigatórias? Sim. As colunas opcionais são preenchidas com valores padrão.
A ordem das colunas importa? Não.
O 202 garante que os custos foram atualizados?
Não, apenas confirma que o arquivo foi recebido e o processamento começou. Você receberá um e-mail quando o processo terminar. Também pode consultar o status com GET /costs/fill-status ou ver o histórico com GET /costs/fill-history.
O que faz o parâmetro fromDate?
Define a partir de que data se aplicam os custos. Se não for enviado, aplicam-se desde o primeiro dia do mês de 2 anos atrás.
É a mesma API Key que uso para a API de dados da Wivo? Sim.
Tem dúvidas? Escreva para contacto@wivoanalytics.com ou acesse a plataforma em app.wivoanalytics.com.
Ao contatar o suporte, inclua: processId (se tiver), código HTTP recebido, e data e hora do erro.