Criar produto
Cadastra um produto novo com seller, categoria, preço e estoque, e devolve o id para as chamadas seguintes.
Use esta operação para colocar um item no catálogo: um ERP que publica um produto novo, um sistema de catálogo que sincroniza a base, um cadastro por planilha. A criação grava o produto, gera o slug da URL a partir do nome, registra o estoque inicial e aciona a indexação para a busca da loja. Para criar milhares de produtos de uma vez, prefira a importação em lote.
Dois campos são obrigatórios além do nome: o seller (quem vende o item) e a categoria. Sem seller o produto não pode ser comprado (o carrinho o recusa), e sem categoria ele some da navegação da loja; por isso a criação rejeita os dois. Imagens, características, variações e faixas de preço são enviadas depois, pelas rotas de cada assunto (veja Produtos).
/api/v1/admin/productsAdminCria um produto
Autenticação: Authorization: Bearer <token> de um usuário administrador com o privilégio manage_catalog. O produto criado por aqui nasce direto no status pedido (não passa pela moderação). Chaves que a rota não conhece são ignoradas sem erro.
Corpo da requisição
namestringobrigatóriovendor_iduuidobrigatóriovendor_required.category_iduuidobrigatórioadditional_category_idsarraypriceintegerobrigatório4990 = R$ 49,90). Zero é permitido (veja zero_price_action); negativo é recusado.list_priceintegerprice.cost_priceintegerskustringbarcodestringncm_codestringvendor_internal_skustringslugstring-2, -3...descriptionstringshort_descriptionstringdescriptionsobjectpt-BR, en) e o valor aceita name, description, short_description, promo_text, highlight_text, seo_title, seo_description e meta_keywords. Idiomas ausentes herdam o texto do idioma padrão.meta_keywordsstringsearch_wordsstringpromo_textstringquantitynumberpadrão: 02.5) só com allow_fractional.low_stock_alertintegerpadrão: 0min_quantitynumberpadrão: 0max_quantitynumberpadrão: 00 = sem máximo). Não pode ser menor que min_quantity quando os dois são positivos.quantity_stepnumberpadrão: 1sale_unitstringpadrão: unun, kg, cx, l, par ou texto livre.sale_unit_labelstringallow_fractionalbooleanpadrão: falseout_of_stock_actionstringpadrão: SNBSN esconde o botão de compra, B aceita encomenda, S mostra o formulário "avise-me".zero_price_actionstringpadrão: RPRAP vende por zero, R bloqueia a compra online, A pede orçamento.avail_sincestringusergroup_idsarrayall, guest, registered). Vazio = todos.popularityintegerpadrão: 0statusstringpadrão: AADHactivedisabledhiddenR e X são recusados.whatsapp_hiddenbooleanpadrão: falseweightnumberlengthnumberwidthnumberheightnumberfree_shippingbooleanpadrão: falseshipping_freightintegerrequires_shippingbooleanpadrão: truefalse para produto digital ou serviço, sem entrega.Exemplo de requisição
curl -X POST "$BASE_URL/api/v1/admin/products" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Caneca Esmaltada 350 ml",
"sku": "CAN-350-AZ",
"price": 4990,
"list_price": 5990,
"cost_price": 2000,
"quantity": 12,
"vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
"category_id": "7ebc648d-6091-4511-8ea2-f86f7b3b4dd9",
"weight": 0.35,
"length": 12,
"width": 9,
"height": 9,
"description": "<p>Caneca esmaltada azul.</p>"
}'Resposta
{
"id": "0df0e614-afe6-4e9c-859b-a7372e9152e4",
"display_id": 10643,
"vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
"category_id": "7ebc648d-6091-4511-8ea2-f86f7b3b4dd9",
"name": "Caneca Esmaltada 350 ml",
"slug": "caneca-esmaltada-350-ml",
"sku": "CAN-350-AZ",
"description": "<p>Caneca esmaltada azul.</p>",
"short_description": "",
"price": 4990,
"list_price": 5990,
"cost_price": 2000,
"track_inventory": true,
"quantity": 12,
"low_stock_alert": 0,
"min_quantity": 0,
"max_quantity": 0,
"quantity_step": 1,
"sale_unit": "un",
"zero_price_action": "R",
"popularity": 0,
"out_of_stock_action": "S",
"weight": 0.35,
"width": 9,
"height": 9,
"length": 12,
"status": "A",
"intended_status": "A",
"approval_status": "approved",
"view_count": 0,
"sales_count": 0,
"rating_avg": 0,
"rating_count": 0,
"free_shipping": false,
"shipping_freight": 0,
"requires_shipping": true,
"vendor_name": "Loja Seller Teste",
"vendor_slug": "loja-seller-teste",
"is_variation": false,
"has_unified_variations": false,
"created_at": "2026-10-11T20:51:07.858767Z",
"updated_at": "2026-10-11T20:51:08.378113Z",
"product_id": "0df0e614-afe6-4e9c-859b-a7372e9152e4",
"product": "Caneca Esmaltada 350 ml",
"product_code": "CAN-350-AZ",
"seo_name": "caneca-esmaltada-350-ml",
"full_description": "<p>Caneca esmaltada azul.</p>",
"price_str": "49.90",
"list_price_str": "59.90",
"amount": 12,
"company_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
"company_name": "Loja Seller Teste",
"main_category": "7ebc648d-6091-4511-8ea2-f86f7b3b4dd9",
"weight_str": "0.350",
"timestamp": 1791751867,
"updated_timestamp": 1791751868,
"images": [],
"price_tiers": []
}Campos da resposta
iduuiddisplay_idintegerstatusstringA, D ou H).slugstring-2, -3 em caso de repetição).*anydescriptions nem linked_orders_count.Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | JSON inválido, ou número em formato inválido | {"error":"invalid request body","detail":"número em formato não aceito: \"abc\". Envie apenas dígitos, sem símbolo de moeda, ponto de milhar ou percentual."} |
| 400 | Sem nome, preço negativo ou sem categoria | {"error":"validation_failed","fields":{"category_id":"category_required"}}. Os códigos dos campos: name_required, invalid_price, category_required |
| 400 | Sem seller | {"error":"vendor_required","detail":"um vendedor precisa ser escolhido..."} |
| 400 | list_price menor que price | {"error":"list_price_below_price","detail":"list_price (500) must be >= price (1000)"} |
| 400 | Nome longo demais | {"error":"name_too_long","detail":"product name exceeds 255 characters"} |
| 400 | Peso ou dimensão negativos; quantidades negativas; max_quantity menor que min_quantity | {"error":"weight must be non-negative"} |
| 400 | zero_price_action ou out_of_stock_action inválidos | {"error":"invalid zero_price_action: \"Z\" (must be P, R, or A)"} |
| 400 | status inválido, ou R/X na criação | {"error":"invalid product status","detail":"invalid product status: \"R\" (must be A/D/H or active/hidden/disabled)"} |
| 400 | Loja que exige código de barras e ele não foi enviado | {"error":"barcode_required: product barcode (EAN/GTIN) is required on this store"} |
| 400 | Loja que exige dados completos de frete e o produto físico ativo não tem peso e dimensões positivos | {"error":"physical_shipping_data_required","detail":"fill positive shipping data (weight, length, width, height) before activating this physical product; save it as disabled while incomplete"} |
| 401 | Sem credenciais, chave inválida ou token expirado | {"error":"invalid or expired token"} |
| 403 | Usuário sem permissão de escrita | {"error":"insufficient privileges","required":"manage_catalog"} |
| 409 | SKU já usado | {"error":"a product with this SKU already exists"} |
| 409 | Loja que proíbe código de barras repetido | {"error":"barcode_exists: a product with this barcode is already registered in this store's catalog; ..."} |
| 429 | Limite de requisições (por exemplo, login repetido) | {"error":"rate limit exceeded","detail":"too many requests, please try again later"} |
| 500 | Falha interna; ou, por limitação conhecida, vendor_id/category_id que não existe, e quantidade fracionada em loja sem suporte | {"error":"failed to create product","detail":"o registro referenciado não existe (campo relacionado a \"category_id\"). Crie ou confira esse registro antes de vinculá-lo."} |
As mensagens de detail que o servidor devolve em português estão como são devolvidas.