Skip to main content
Para cargas grandes (carga inicial, migração, sync diário pesado), use o pipeline assíncrono de bulk import. Limites:
  • Arquivo até 100 MB (alinhado com Shopify)
  • Formato JSONL (uma linha por item, mesmo schema do POST /items/upsert)
  • Até 5 jobs simultâneos por catálogo

Fluxo completo

1

POST /imports — cria job + signed URL

A Voop responde com jobId + uploadUrl. A URL é assinada e válida por 1 hora.
2

PUT {uploadUrl} — upload do JSONL para R2

Faça PUT direto na uploadUrl. Não passa pela API da Voop — vai direto para o R2 (sem custo de banda intermediária).
Cada linha do catalog.jsonl é o payload de POST /items/upsert:
3

POST /imports/{jobId}/start — enfileira para processar

O backend abre stream do R2, lê linha-a-linha, valida com Zod, e faz upsert em batches transacionais de 100. Erros isolados não param o batch.
4

GET /imports/{jobId} — pollingdo status

Quando status for terminal (completed, completed_with_errors, failed, cancelled), o import.completed ou import.failed webhook é disparado.
5

GET /imports/{jobId}/errors — erros por linha

Ao final, se errorCount > 0, baixe a lista de erros (paginada):
Filtre por errorType (validation, database, conflict, reference).

Por que JSONL?

  • Streamable: o backend lê linha-a-linha sem carregar 100MB em memória
  • Tolerante: linha mal-formatada não corrompe o resto do arquivo
  • Padrão: usado pelo Shopify, BigQuery, AWS Athena, etc.
  • Diff-friendly: se você gera o arquivo deterministicamente, pode usar diff entre rodadas

Recomendações de geração

  • Use UTF-8, terminadores \n (não \r\n)
  • 1 produto por linha — sem indentação
  • Linhas vazias são ignoradas (tolerante)
  • Não envolva em array JSON: o arquivo NÃO é [{...}, {...}], é {...}\n{...}

Exemplo Node.js de geração