Rotas de lote dedicadas
Quatro rotas de finalidade única para mudar status, excluir, mudar preços ou mover produtos de categoria em lote.
Estas quatro rotas fazem o mesmo trabalho das ações update_status, delete, update_price e update_category de Ações em lote, cada uma na sua URL e com um corpo mais simples. Use se preferir uma rota por intenção. As quatro aceitam os mesmos recursos de segurança: simulate, filter, confirm_token, e devolvem um undo_id que pode ser desfeito.
Todas exigem o privilégio manage_catalog e recebem os ids como UUIDs de produto. O dinheiro é em centavos; os percentuais, em pontos-base.
Mudar o status
/api/v1/admin/products/bulk/statusAdminMudar o status de muitos produtos
Corpo da requisição
product_idsarrayobrigatóriofilter.statusstringobrigatórioADHactivedisabledhiddeninactiveR e X (resultados de moderação) são recusados.filterobjectsimulatebooleanpadrão: falseconfirm_tokenstringcurl -X POST "$BASE_URL/api/v1/admin/products/bulk/status" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"product_ids":["ea4e5a3d-bed2-4bcc-bce4-53a8370cee28"],"status":"hidden"}'Excluir produtos
/api/v1/admin/products/bulk/deleteAdminMandar muitos produtos para a lixeira
Os produtos saem do catálogo e da loja e vão para a lixeira; o lote devolve um undo_id que os restaura.
Corpo da requisição
product_idsarrayobrigatóriofilter.filterobjectsimulatebooleanpadrão: falsenew_value: "deleted".confirm_tokenstringcurl -X POST "$BASE_URL/api/v1/admin/products/bulk/delete" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"product_ids":["ea4e5a3d-bed2-4bcc-bce4-53a8370cee28"]}'Mudar preços
/api/v1/admin/products/bulk/pricesAdminMudar o preço de venda de muitos produtos
Muda somente o preço de venda. Qualquer chave além das abaixo é recusada com unknown_fields, para que um corpo pensado para o preço de custo não sobrescreva em silêncio o preço de venda (para mudar o custo, use PUT /api/v1/admin/products/{id} com cost_price, um produto por chamada).
Corpo da requisição
product_idsarrayobrigatóriofilter.typestringobrigatórioabsoluteincreasedecreasepercentage_increasepercentage_decreaseabsolute define o preço (centavos, acima de zero). increase e decrease somam ou subtraem centavos (nunca abaixo de zero). Os tipos percentage_* usam pontos-base (500 = 5%, máximo 10000).valueintegerobrigatóriotype.filterobjecttype e value continuam definindo a mudança.simulatebooleanpadrão: falseconfirm_tokenstringcurl -X POST "$BASE_URL/api/v1/admin/products/bulk/prices" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"product_ids":["ea4e5a3d-bed2-4bcc-bce4-53a8370cee28"],"type":"percentage_increase","value":1000}'Mover para outra categoria
/api/v1/admin/products/bulk/move-categoryAdminMover muitos produtos para outra categoria
O destino vira a categoria principal de cada produto (o vínculo anterior com a categoria principal é substituído).
Corpo da requisição
product_idsarrayobrigatóriofilter.category_iduuidobrigatóriofilterobjectsimulatebooleanpadrão: falseconfirm_tokenstringcurl -X POST "$BASE_URL/api/v1/admin/products/bulk/move-category" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"product_ids":["ea4e5a3d-bed2-4bcc-bce4-53a8370cee28"],"category_id":"7ebc648d-6091-4511-8ea2-f86f7b3b4dd9"}'Resposta
{
"total_requested": 2,
"total_affected": 2,
"message": "Updated prices for 2 products (percentage_increase)",
"undo_id": "ad40a3ab-042f-4495-bb33-c44cb51cfdff"
}{
"total_requested": 2,
"total_affected": 0,
"message": "simulation",
"preview": [
{ "product_id": "ea4e5a3d-bed2-4bcc-bce4-53a8370cee28", "name": "Camiseta Azul", "current_value": "4990", "new_value": "5489", "ok": true }
]
}As respostas de um lote por filter (simulação com confirm_token, resultado 200, tarefa 202) são as mostradas em Ações em lote.
Campos da resposta
total_requestedintegertotal_affectedinteger0 numa simulação.messagestringsimulation numa simulação.undo_idstringPOST /api/v1/admin/bulk-undo/{undo_id}.failed_idsarraypreviewarrayproduct_id, name, current_value, new_value, ok, reason.Erros
| Status | Quando | Exemplo de corpo |
|---|---|---|
| 400 | JSON inválido | {"error":"invalid request body","detail":"..."} |
| 400 | Sem ids e sem filtro | {"error":"product_ids is required","detail":""} |
| 400 | status ausente ou não aceito | {"error":"status is required"} ou {"error":"invalid product status","detail":"..."} |
| 400 | Preços: type ausente ou desconhecido | {"error":"type is required"} ou {"error":"invalid bulk price update","detail":"invalid price update type: percentage (must be absolute, increase, decrease, percentage_increase, or percentage_decrease) ..."} |
| 400 | Preços: value ausente ou zero | {"error":"value is required","detail":"..."} ou {"error":"value cannot be zero","detail":"..."} |
| 400 | Preços: chaves a mais no corpo | {"error":"unknown_fields","detail":"campos que esta rota não aceita: field. Aceitos: product_ids, type, value, simulate. ..."} |
| 400 | Preços: a mudança deixaria um produto em zero, ou percentual acima de 10000 | {"error":"invalid bulk price update","detail":"esta mudança deixaria 1 produto(s) valendo ZERO. ..."} |
| 400 | category_id ausente ou não é UUID | {"error":"category_id is required"} |
| 404 | Categoria de destino não encontrada | {"error":"category not found","detail":"nenhuma categoria ativa com o id ..."} |
| 400 / 409 / 428 | Problemas de filtro (filtro inválido, token inválido ou expirado, simulação ausente) | invalid_filter, confirm_token_invalid, simulate_required |
| 401 / 403 | Sem token / sem manage_catalog | {"error":"missing authorization header"} / {"error":"insufficient privileges","required":"manage_catalog"} |