Referência da API
Criar produto
Cria um produto no seu catálogo. Produto sozinho não é vendável — você precisa criar pelo menos uma `Offer` vinculada (`POST /v2/offers`) com o preço e ciclo de cobrança. **Imagem do produto:** este endpoint **não aceita** `imageUrl` no corpo. Crie o produto primeiro e depois envie a imagem em [POST /v2/products/:id/image](/docs/api/upload-product-image). A chave de API precisa da permissão `isInvoiceAvailable`.
/v2/productsimageUrl Enviar `imageUrl` aqui retorna 400. A imagem é hospedada no nosso S3 e enviada via multipart em `POST /v2/products/:id/image`.Autenticação
HTTP Basic Auth. Envie sua secret key no header:
Authorization: Basic {base64(secret:SUA_SECRET_KEY)}Parâmetros
namestringobrigatórioNome do produto. Mostrado no checkout, comprovantes e e-mails.
Exemplo: Curso de Marketing Digital
descriptionstringopcionalDescrição do produto. Texto livre.
Exemplo: Curso completo com 50 horas de aulas e certificado
externalIdstringopcionalSua referência interna pra esse produto (ID de ERP, SKU, etc). Único por conta. Se omitido, o servidor não gera automático — fica `null`.
Exemplo: curso-mkt-2026
metadataobjectopcionalObjeto JSON arbitrário pra anexar informação do seu sistema.
Exemplo: { "category": "education" }
Body da requisição
Content-Type: application/json
{
"name": "Curso de Marketing Digital",
"description": "Curso completo com 50 horas de aulas e certificado",
"externalId": "curso-mkt-2026",
"metadata": { "category": "education", "language": "pt-BR" }
}Respostas
Produto criado sem imagem (imageUrl: null). Pra anexar imagem, use POST /v2/products/:id/image em seguida.
{
"id": "prd_111aaa-bbb-ccc",
"createdByUserId": "u-1234",
"name": "Curso de Marketing Digital",
"description": "Curso completo com 50 horas de aulas e certificado",
"imageUrl": null,
"externalId": "curso-mkt-2026",
"active": true,
"metadata": { "category": "education", "language": "pt-BR" },
"deletedAt": null,
"createdAt": "2026-05-26T14:32:01.923Z",
"updatedAt": "2026-05-26T14:32:01.923Z"
}Erro de validação. Causas comuns: nome fora dos limites, imageUrl enviado no corpo (use endpoint separado), externalId já existe.
{
"status": 400,
"error": "imageUrl nao eh aceito aqui. Crie o produto e depois envie a imagem em POST /v2/products/:id/image."
}Exemplos
curl -X POST "https://api.pagnovo.com/v2/products" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "Curso de Marketing Digital",
"description": "Curso completo com 50 horas de aulas",
"externalId": "curso-mkt-2026"
}'const token = Buffer.from("secret:" + process.env.PAGNOVO_SECRET_KEY).toString("base64");
// Fluxo típico: cria Product, depois cria Offers vinculadas
const product = await fetch("https://api.pagnovo.com/v2/products", {
method: "POST",
headers: { Authorization: `Basic ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
name: "Curso de Marketing Digital",
externalId: "curso-mkt-2026",
}),
}).then(r => r.json());
// Cria uma offer one-time de R$ 497
await fetch("https://api.pagnovo.com/v2/offers", {
method: "POST",
headers: { Authorization: `Basic ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
productId: product.id,
name: "Pagamento único",
amount: 49700, // R$ 497 em centavos
// billingCycle ausente = one-time
}),
});