Importar imagens, XML e URL
Carrega imagens de produtos de um arquivo ZIP, envia um XML ou baixa uma planilha de uma URL para o assistente de importação.
Estas três rotas cobrem entradas que não são uma planilha comum. Uma carrega fotos em lote a partir de um ZIP, e as outras duas trazem o arquivo de fora (um XML de um fornecedor, uma planilha publicada em uma URL) para o assistente de importação em etapas, que você termina com Validar e Executar.
/api/v1/admin/import/product-images-zipAdminImporta imagens de produtos de um ZIP
Privilégio manage_catalog. Envie um ZIP em multipart/form-data, no campo file. Cada arquivo dentro do ZIP é ligado a um produto pelo nome, no formato {sku}[.sufixo].{extensão}. A busca ignora maiúsculas e minúsculas e só considera produtos ativos (não excluídos).
Para dar várias imagens ao mesmo SKU, use sufixos: ABC-123.jpg, ABC-123-2.jpg, ABC-123_back.png. A plataforma tenta primeiro o nome inteiro como SKU e depois o nome sem o sufixo. A primeira imagem de um produto que ainda não tem foto vira a imagem principal.
Corpo da requisição (multipart/form-data)
filefileobrigatório.zip. Até 250 MB e 5.000 entradas. Cada imagem pode ter até 25 MB. Extensões: jpg, jpeg, png, gif, webp, avif, svg./api/v1/admin/import/xmlAdminEnvia um XML para o assistente de importação
Privilégio manage_settings. Converte um XML em linhas e colunas e abre um job de importação de produtos. Cada elemento filho do item vira uma coluna. Exemplo de estrutura aceita:
<products>
<product>
<sku>CAM-001</sku>
<name>Camiseta Algodão</name>
<price>49.90</price>
</product>
</products>Corpo da requisição (multipart/form-data)
filefileobrigatório.xml.item_elementstringpadrão: productroot_elementstring/api/v1/admin/import/from-urlAdminBaixa um arquivo de uma URL para o assistente
Privilégio manage_settings. A plataforma baixa o arquivo no servidor (até 100 MB, no máximo 5 redirecionamentos, 60 segundos) e abre um job de importação. Só http e https; endereços internos, privados e de loopback são bloqueados, inclusive depois de um redirecionamento.
Corpo da requisição (JSON)
urlstringobrigatório.csv, .xlsx, .xml...).Exemplo de requisição
# ZIP de imagens (CAM-001.jpg, CAM-001-2.jpg, ...)
curl "$BASE_URL/api/v1/admin/import/product-images-zip" \
-H "Authorization: Bearer $TOKEN" -F "file=@fotos.zip"
# XML do fornecedor
curl "$BASE_URL/api/v1/admin/import/xml" \
-H "Authorization: Bearer $TOKEN" -F "file=@fornecedor.xml" -F "item_element=product"
# planilha publicada em uma URL
curl "$BASE_URL/api/v1/admin/import/from-url" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"url":"https://fornecedor.example.com/catalogo.csv"}'Resposta
{
"total": 3,
"stored": 2,
"skipped": 1,
"errors": 0,
"items": [
{ "entry": "CAM-001.jpg", "sku": "CAM-001", "matched": true, "stored": true, "url": "/uploads/dfe2555e/product/6a1f/CAM-001.jpg" },
{ "entry": "CAM-001-2.jpg", "sku": "CAM-001", "matched": true, "stored": true, "url": "/uploads/dfe2555e/product/6a1f/CAM-001-2.jpg" },
{ "entry": "XYZ-999.jpg", "sku": "XYZ-999", "matched": false, "stored": false, "message": "no active product matched filename sku candidates [\"XYZ-999\"]" }
]
}{
"job_id": "32fcf16e-4931-4ec9-8257-10c887579d40",
"file_name": "p.xml",
"total_rows": 1,
"csv_columns": ["sku", "name", "price"],
"detected_delimiter": ";",
"preview_rows": [["DOCS-XML-1", "Caneca Docs", "29.90"]],
"auto_mapping": { "name": "name", "price": "price", "sku": "sku" }
}Campos da resposta (ZIP)
totalintegerstoredintegerskippedintegererrorsintegeritemsarrayentry (nome no ZIP), sku (lido do nome), matched (achou produto), stored (gravou), url (endereço público da imagem, quando gravou) e message (motivo, quando não gravou).notestringCampos da resposta (XML e URL)
job_iduuidvalidate e execute.file_namestringtotal_rowsintegercsv_columnsarraydetected_delimiterstring;.preview_rowsarraycsv_columns.auto_mappingobjectavailable_fieldsarrayErros
| Status | Quando | Corpo de exemplo |
|---|---|---|
| 400 | Campo file ausente | {"error":"missing file field in form","detail":"http: no such file"} |
| 400 | ZIP inválido ou grande demais | {"error":"import product images zip failed","detail":"open zip: zip: not a valid zip file"} |
| 400 | URL com esquema que não é http ou https | {"error":"invalid_url","detail":"invalid_scheme: only http and https are allowed"} |
| 400 | URL de endereço interno | {"error":"invalid_url","detail":"ssrf_forbidden: url targets internal/private/loopback address"} |
| 400 | JSON sem url | {"error":"url is required"} |
| 401 | Token ausente ou expirado | {"error":"invalid or expired token"} |
| 403 | Falta o privilégio da rota | {"error":"insufficient privileges","required":"manage_settings"} |
| 415 | /import/xml: extensão não aceita | {"error":"unsupported file type","detail":"..."} |
| 500 | Falha ao baixar a URL (status diferente de 200, tempo esgotado) ou ao ler o XML | {"error":"import from URL failed","detail":"URL returned status 404"} |