VenddorDocumentação API
API atualAPI legada
Guia rápidoReferência completa
Carregando índice…
API atual/Referência completa/Importação e exportação

Importar produtos

Envia uma planilha de produtos (ou uma URL) para criar e atualizar o catálogo, com pré-visualização sem gravar e modelo de planilha.

Use esta página para carregar produtos em lote: a carga inicial de uma loja nova, a atualização diária de preço e estoque vinda de um ERP, ou a migração de outra plataforma. A importação é um upsert pelo SKU: um SKU que não existe cria o produto, um SKU que já existe atualiza.

O caminho seguro tem três passos. Baixe o modelo, rode a pré-visualização (não grava produtos e mostra o que aconteceria, linha a linha) e só então importe. Para controle fino de colunas, valores padrão e transformações, use o assistente em Importação avançada.

O SKU é a chave da atualização

Se a linha não tiver SKU, a plataforma inventa um (IMP-<linha>-<número>). Reenviar a mesma planilha sem SKU cria os produtos de novo, duplicados. Sempre preencha product_code.

GET/api/v1/admin/import/products/templateAdmin

Baixa o modelo de importação de produtos

Privilégio manage_catalog. Devolve o mesmo CSV de /export/products/template: products_template, separador ;, com o BOM do UTF-8 e duas linhas de exemplo.

POST/api/v1/admin/import/products/previewAdmin

Simula a importação sem gravar produtos

Privilégio manage_catalog. Roda toda a validação da importação e responde o que seria criado, atualizado ou recusado, sem gravar nenhum produto. A chamada registra um job de preparação (o arquivo fica guardado temporariamente), mas nada entra no catálogo. Envie multipart/form-data.

Corpo da requisição (multipart/form-data)

filefileobrigatório
Planilha .csv, .txt, .xml, .xlsx ou .xlsm.
field_mappingsstring
JSON em texto que liga o nome de cada coluna da planilha ao campo do produto, por exemplo {"product_code":"sku","price":"price"}. Se omitido, a plataforma mapeia as colunas pelo nome.
strategystringpadrão: create_update
create_updateupsertupdate_onlycreate_only
create_update e upsert criam e atualizam; update_only só atualiza SKUs que já existem; create_only só cria.
default_vendor_iduuid
Seller que recebe as linhas sem vendor_id.
POST/api/v1/admin/import/productsAdmin

Importa produtos de um arquivo ou de uma URL

Privilégio manage_catalog. Aceita dois formatos de corpo, escolhidos pelo Content-Type:

  • multipart/form-data com o arquivo no campo file;
  • application/json com {"url": "https://..."}: a plataforma baixa o arquivo (até 100 MB, só http e https, endereços internos são bloqueados) e importa em segundo plano.

Com arquivo pequeno e opções padrão, a importação é síncrona: grava na hora e responde 200 com o resumo. É pequeno o arquivo com até 256 linhas de dados e até 1 MiB. Acima disso, ou se você mandar qualquer opção diferente do padrão (strategy, update_existing=false, skip_errors=false, vendor_id), a importação vira um job: responde 202 com job_id e você acompanha em Jobs de importação.

Corpo da requisição (multipart/form-data)

filefileobrigatório
Planilha .csv, .txt, .xml, .xlsx ou .xlsm.
strategystringpadrão: import_all
import_allupdate_existingcreate_new
import_all cria e atualiza; update_existing só atualiza; create_new só cria. Outro valor volta 400.
update_existingbooleanpadrão: true
Quando false, linhas cujo SKU já existe são puladas.
skip_errorsbooleanpadrão: true
Quando true, uma linha com erro é registrada e o resto continua. Quando false, a importação para na primeira linha com erro (as linhas anteriores já foram gravadas).
vendor_iduuid
Seller padrão das linhas que não trazem vendor_id.

Corpo da requisição (application/json)

urlstringobrigatório
Endereço público do arquivo. Sempre assíncrono, com as opções padrão.

Colunas da planilha

Os nomes não diferenciam maiúsculas de minúsculas e a ordem não importa.

Colunas

product_codestring
SKU, a chave do upsert (também vale sku). Até 128 caracteres.
namestringobrigatório
Nome do produto. Até 512 caracteres. Tags HTML são removidas.
pricestringobrigatório
Preço de venda em reais: 49,90, 49.90 ou R$ 49,90. Negativo é recusado.
list_pricestring
Preço "de" (riscado), no mesmo formato. Vazio mantém o valor atual.
statusstring
AHD
Status do produto. Letra ou palavra. Valor que a plataforma não reconhece vira ativo e gera um aviso.
quantityinteger
Estoque. Também vale stock_quantity. 1,00 é lido como 1; um valor que não é número inteiro recusa a linha.
weightnumber
Peso em kg, com vírgula ou ponto decimal.
category_idstring
Categoria do produto.
vendor_idstring
Seller dono do produto. Produto novo exige esta coluna (ou o vendor_id do formulário).
slugstring
Trecho da URL. Também vale url_key. Vazio gera a partir do nome.
descriptionstring
Descrição em HTML. Até 65.535 caracteres. HTML perigoso (scripts, atributos de evento) é removido.
short_descriptionstring
Resumo. Também vale short_desc.

Exemplo de requisição

bash
# 1) pré-visualizar
curl "$BASE_URL/api/v1/admin/import/products/preview" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@produtos.csv" -F "strategy=upsert"

# 2) importar de verdade
curl "$BASE_URL/api/v1/admin/import/products" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@produtos.csv"

# 3) importar de uma URL (sempre assíncrono)
curl "$BASE_URL/api/v1/admin/import/products" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"url":"https://erp.example.com/exports/produtos.csv"}'

Resposta

200Importação síncrona concluída
json
{
  "total": 2,
  "created": 1,
  "imported": 1,
  "updated": 1,
  "skipped": 0,
  "errors": [],
  "warnings": []
}
202Importação em segundo plano
json
{
  "job_id": "7aa94252-0df6-4293-8404-c0ffc2a96fbc",
  "status": "processing",
  "status_url": "/admin/import/jobs/7aa94252-0df6-4293-8404-c0ffc2a96fbc",
  "total_rows": 12840
}
200Pré-visualização
json
{
  "job_id": "f74f38fb-7010-4c92-99ee-296a11f8d315",
  "total_rows": 2,
  "would_create": 1,
  "would_update": 0,
  "would_skip": 1,
  "errors_by_row": [
    {
      "row": 3,
      "field": "vendor_id,name",
      "message": "produto novo exige vendor_id, name — selecione o \"Vendedor padrão\" ou mapeie uma coluna para vendor_id"
    }
  ],
  "preview_rows": [
    {
      "row_number": 2,
      "action": "create",
      "data": { "name": "Camiseta Docs Teste", "price": "49,90", "product_code": "DOCS-API-001", "quantity": "10", "status": "A", "vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36" }
    },
    {
      "row_number": 3,
      "action": "error",
      "data": { "name": "", "price": "19,90", "product_code": "DOCS-API-002", "quantity": "5", "status": "A", "vendor_id": "" },
      "error": "produto novo exige vendor_id, name — selecione o \"Vendedor padrão\" ou mapeie uma coluna para vendor_id"
    }
  ],
  "valid": false
}

Campos da resposta (200 síncrono)

totalinteger
Linhas de dados lidas.
createdinteger
Produtos criados. imported repete o mesmo número (nome antigo).
updatedinteger
Produtos atualizados.
skippedinteger
Linhas puladas por erro.
errorsarray
Problemas por linha: row (número da linha na planilha, o cabeçalho é a linha 1), field (pode faltar) e message. Sempre presente, mesmo vazio. Avisos como "status não reconhecido" também aparecem aqui.
warningsarray
Linhas importadas, mas não exatamente como escritas (por exemplo, slug que precisou de sufixo). Sempre presente.

Campos da resposta (202)

job_iduuid
Id do job.
statusstring
Sempre processing na criação.
status_urlstring
Caminho para consultar o job, sem o prefixo /api/v1. Monte a URL como /api/v1 + status_url.
total_rowsinteger
Linhas de dados no arquivo.

Campos da resposta (pré-visualização)

job_iduuid
Job de preparação criado pela pré-visualização.
total_rowsinteger
Linhas de dados.
would_createinteger
Quantos produtos seriam criados.
would_updateinteger
Quantos seriam atualizados.
would_skipinteger
Quantas linhas seriam puladas.
errors_by_rowarray
Erros por linha (row, field, message). null quando não há erro.
preview_rowsarray
As primeiras linhas boas e as primeiras com erro. action é create, update, skip ou error; data mostra os valores já ligados aos campos; error só aparece quando action é error.
validboolean
true quando não há nenhum erro.

Erros

StatusQuandoCorpo de exemplo
400Campo file ausente{"error":"missing file field in form","detail":"http: no such file"}
400Arquivo vazio{"error":"csv_empty","detail":"uploaded file is empty"}
400Falta a coluna name ou price{"error":"missing_required_column","detail":"missing required column: price"}
400Linha em branco no meio da planilha{"error":"csv_empty_row","detail":"..."}
400strategy fora da lista{"error":"invalid strategy","detail":"strategy must be import_all, update_existing or create_new"}
400JSON sem url, ou URL recusada{"error":"url is required"}
400Planilha Excel corrompida{"error":"invalid spreadsheet","detail":"..."}
401Token ausente ou expirado{"error":"invalid or expired token"}
403Falta manage_catalog{"error":"insufficient privileges","required":"manage_catalog"}
415Extensão não aceita{"error":"unsupported file type","detail":"only CSV, XLSX and XML files are accepted (got \".pdf\")"}
500Falha ao importar{"error":"import products failed","detail":"..."}

As mensagens por linha (produto novo exige vendor_id...) saem em português do servidor.

Atenção ao 200 com erros dentro

Uma importação com skip_errors ligado devolve 200 mesmo quando várias linhas falharam. O sucesso do pedido não é o sucesso das linhas: confira skipped e a lista errors antes de dar o trabalho por terminado.

Vendedor por nome

No modelo, a coluna vendor_id diz "Nome do vendedor (ou slug/e-mail/ID)", e a pré-visualização resolve o seller por nome. Para não depender disso, prefira o UUID do seller.

Veja também

  • Jobs de importação
  • Importação avançada
  • Modelos de planilha
Anterior
Modelos de planilha
Próxima
Jobs de importação
Nesta página
  • Exemplo de requisição
  • Resposta
  • Erros
  • Veja também