Plasma

Produtos

API completa para criar, listar, atualizar e remover produtos.

Visão Geral

A API de Produtos permite gerenciar todo o catálogo da sua loja. Você pode criar, listar, atualizar e remover produtos programaticamente.

Todo valor monetário da API é em centavos inteiros. Campos que carregam dinheiro terminam em Cents: priceCents, compareAtPriceCents. 7990 é R$ 79,90, e não R$ 7.990,00.

Enviar 79.90 em priceCents é rejeitado com 422, porque o campo só aceita inteiro. Converta antes: Math.round(reais * 100).

Endpoints

MétodoEndpointDescrição
GET/api/sdk/productsListar produtos
POST/api/sdk/productsCriar produto
GET/api/sdk/products/:idBuscar produto
PATCH/api/sdk/products/:idAtualizar produto
DELETE/api/sdk/products/:idRemover produto

Listar Produtos

GET /api/sdk/products

Parâmetros de Query

ParâmetroTipoDescrição
limitnumberMáximo de itens (1-100, padrão: 50)
cursorstringCursor para paginação
statusstringFiltrar por status: active, draft, archived
searchstringBuscar por título, descrição ou SKU
productTypestringFiltrar por tipo de produto
vendorstringFiltrar por fornecedor
skustringFiltrar por SKU exato
sortBystringOrdenar por: createdAt, updatedAt, title, priceCents, inventory
sortOrderstringOrdem: asc ou desc (padrão: desc)

Exemplo de Requisição

curl -X GET "https://api.plasmacheckout.com/api/sdk/products?limit=10&status=active" \
  -H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx"
const response = await fetch(
  'https://api.plasmacheckout.com/api/sdk/products?limit=10&status=active',
  {
    headers: {
      'X-PLASMA-Public-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxx',
      'X-PLASMA-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxx'
    }
  }
);

const result = await response.json();
console.log(result.data);        // array de produtos
console.log(result.pagination);  // { hasMore, nextCursor, count, total }
import requests

response = requests.get(
    'https://api.plasmacheckout.com/api/sdk/products',
    headers={
        'X-PLASMA-Public-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxx',
        'X-PLASMA-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxx'
    },
    params={'limit': 10, 'status': 'active'}
)

data = response.json()
print(data['data'])        # lista de produtos
print(data['pagination'])  # { hasMore, nextCursor, count, total }

Resposta

{
  "data": [
    {
      "id": "cm5abc123def456ghi789",
      "title": "Camiseta Premium",
      "description": "Camiseta 100% algodão",
      "priceCents": 7990,
      "compareAtPriceCents": 9990,
      "sku": "CAM-001",
      "status": "active",
      "productType": "Vestuário",
      "vendor": "Minha Marca",
      "images": ["https://..."],
      "imageUrl": "https://...",
      "inventory": 100,
      "trackInventory": true,
      "tags": ["algodão", "premium"],
      "options": [],
      "variants": [],
      "createdAt": "2025-01-15T10:00:00Z",
      "updatedAt": "2025-01-15T10:00:00Z"
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "cm5abc123def456ghi790",
    "count": 10,
    "total": 150
  },
  "filters": {
    "status": "active",
    "search": null,
    "productType": null,
    "vendor": null
  }
}

Paginação com Cursor

Para buscar a próxima página, use o nextCursor retornado:

curl -X GET "https://api.plasmacheckout.com/api/sdk/products?limit=10&cursor=cm5abc123def456ghi790" \
  -H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx"

Quando hasMore for false, não há mais produtos. O campo nextCursor será null.


Criar Produto

POST /api/sdk/products

Body

CampoTipoObrigatórioDescrição
titlestring✅Título do produto (max 255)
priceCentsinteger✅Preço em centavos inteiros (≥ 0). 7990 é R$ 79,90
descriptionstring❌Descrição (max 5000)
compareAtPriceCentsinteger❌Preço comparativo em centavos (deve ser maior que priceCents)
skustring❌SKU único por loja (max 100)
statusstring❌active, draft, archived (padrão: active)
productTypestring❌Tipo de produto
vendorstring❌Fornecedor
imagesarray❌URLs das imagens (max 10)
imageUrlstring❌URL da imagem principal
inventorynumber❌Quantidade em estoque (padrão: 0)
trackInventoryboolean❌Controlar estoque (padrão: true)
tagsstring[]❌Tags do produto

Exemplo

curl -X POST "https://api.plasmacheckout.com/api/sdk/products" \
  -H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Camiseta Premium",
    "description": "Camiseta 100% algodão, confortável e durável",
    "priceCents": 7990,
    "compareAtPriceCents": 9990,
    "sku": "CAM-001",
    "status": "active",
    "productType": "Vestuário",
    "vendor": "Minha Marca",
    "inventory": 50,
    "trackInventory": true,
    "tags": ["algodão", "premium"],
    "images": [
      "https://exemplo.com/imagem1.jpg",
      "https://exemplo.com/imagem2.jpg"
    ]
  }'
const response = await fetch('https://api.plasmacheckout.com/api/sdk/products', {
  method: 'POST',
  headers: {
    'X-PLASMA-Public-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxx',
    'X-PLASMA-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    title: 'Camiseta Premium',
    description: 'Camiseta 100% algodão, confortável e durável',
    priceCents: 7990,
    compareAtPriceCents: 9990,
    sku: 'CAM-001',
    status: 'active',
    productType: 'Vestuário',
    vendor: 'Minha Marca',
    inventory: 50,
    trackInventory: true,
    tags: ['algodão', 'premium'],
    images: [
      'https://exemplo.com/imagem1.jpg',
      'https://exemplo.com/imagem2.jpg'
    ]
  })
});

const result = await response.json();
console.log(result.data);     // produto criado
console.log(result.message);  // "Product created successfully"

Resposta (201 Created)

{
  "data": {
    "id": "cm5abc123def456ghi789",
    "title": "Camiseta Premium",
    "description": "Camiseta 100% algodão, confortável e durável",
    "priceCents": 7990,
    "compareAtPriceCents": 9990,
    "sku": "CAM-001",
    "status": "active",
    "productType": "Vestuário",
    "vendor": "Minha Marca",
    "images": ["https://exemplo.com/imagem1.jpg", "https://exemplo.com/imagem2.jpg"],
    "imageUrl": "https://exemplo.com/imagem1.jpg",
    "inventory": 50,
    "trackInventory": true,
    "tags": ["algodão", "premium"],
    "options": [],
    "variants": [],
    "createdAt": "2025-01-15T10:00:00Z",
    "updatedAt": "2025-01-15T10:00:00Z"
  },
  "message": "Product created successfully"
}

Ao criar um produto, o webhook product.created é disparado, com o produto inteiro em data.

Variantes são cadastradas no painel, em Produtos. A criação e a edição pela API ainda não aceitam variantes; a leitura devolve todas.


Variantes

Um produto pode ter variantes: tamanho, cor, volume. Cada variante tem o próprio preço, estoque e SKU.

Um produto com variantes (trecho)
{
  "id": "cmu1splash0001",
  "title": "Body Splash Lavanda",
  "priceCents": 2990,
  "options": ["Volume"],
  "variants": [
    { "id": "cmu1var5ml", "title": "5ml", "optionValues": ["5ml"], "sku": "BSL-5",
      "priceCents": 2990, "compareAtPriceCents": null, "inventory": 10, "trackInventory": true, "position": 0 },
    { "id": "cmu1var10ml", "title": "10ml", "optionValues": ["10ml"], "sku": "BSL-10",
      "priceCents": 4990, "compareAtPriceCents": null, "inventory": 3, "trackInventory": true, "position": 1 }
  ]
}
CampoDescrição
optionsNomes dos atributos, como ["Tamanho", "Cor"]. Vazio quando o produto não tem variantes
variants[].idO variantId que o carrinho manda ao criar o checkout
variants[].titleNome da variante, como 10ml ou P / Azul
variants[].optionValuesValores dos atributos, na mesma ordem de options
variants[].priceCentsPreço da variante, em centavos
variants[].inventoryEstoque da variante
variants[].positionOrdem definida pelo lojista; a lista já vem ordenada

Regras para montar a vitrine:

  1. variants vazia: o próprio produto é o que se vende. Preço e estoque são os do produto, e o carrinho o pede sem variantId.
  2. Com variantes: preço e estoque valem por variante; os do produto ficam só como referência. Monte o seletor com options e optionValues, e o carrinho tem de dizer qual variante quer.
  3. Estoque nunca impede uma venda. Mostrar "últimas unidades" ou esconder um item zerado é decisão da sua vitrine.

Buscar Produto

GET /api/sdk/products/:id

Exemplo

curl -X GET "https://api.plasmacheckout.com/api/sdk/products/cm5abc123def456ghi789" \
  -H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx"
const response = await fetch(
  'https://api.plasmacheckout.com/api/sdk/products/cm5abc123def456ghi789',
  {
    headers: {
      'X-PLASMA-Public-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxx',
      'X-PLASMA-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxx'
    }
  }
);

const { data } = await response.json();

Resposta

{
  "data": {
    "id": "cm5abc123def456ghi789",
    "title": "Camiseta Premium",
    "description": "Camiseta 100% algodão",
    "priceCents": 7990,
    "compareAtPriceCents": 9990,
    "sku": "CAM-001",
    "status": "active",
    "productType": "Vestuário",
    "vendor": "Minha Marca",
    "images": ["https://..."],
    "imageUrl": "https://...",
    "inventory": 50,
    "trackInventory": true,
    "tags": ["algodão", "premium"],
    "options": [],
    "variants": [],
    "createdAt": "2025-01-15T10:00:00Z",
    "updatedAt": "2025-01-15T10:00:00Z"
  }
}

Produto Não Encontrado (404)

{
  "error": "Product not found",
  "code": "NOT_FOUND"
}

Atualizar Produto

PATCH /api/sdk/products/:id

Apenas os campos enviados serão atualizados (update parcial). O body aceita os mesmos campos de criação.

Exemplo

curl -X PATCH "https://api.plasmacheckout.com/api/sdk/products/cm5abc123def456ghi789" \
  -H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "priceCents": 6990,
    "compareAtPriceCents": 8990,
    "inventory": 30
  }'
const response = await fetch(
  'https://api.plasmacheckout.com/api/sdk/products/cm5abc123def456ghi789',
  {
    method: 'PATCH',
    headers: {
      'X-PLASMA-Public-Key': 'pk_live_xxxxxxxxxxxxxxxxxxxx',
      'X-PLASMA-Secret-Key': 'sk_live_xxxxxxxxxxxxxxxxxxxx',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      priceCents: 6990,
      compareAtPriceCents: 8990,
      inventory: 30
    })
  }
);

const { data, message } = await response.json();

Resposta

{
  "data": {
    "id": "cm5abc123def456ghi789",
    "title": "Camiseta Premium",
    "priceCents": 6990,
    "compareAtPriceCents": 8990,
    "inventory": 30,
    "status": "active",
    "updatedAt": "2025-01-15T11:00:00Z"
  },
  "message": "Product updated successfully"
}

Ao atualizar um produto, o webhook product.updated é disparado, com o produto inteiro em data.


Remover Produto

DELETE /api/sdk/products/:id

A remoção é permanente. O produto é deletado do banco de dados e não pode ser recuperado.

Exemplo

curl -X DELETE "https://api.plasmacheckout.com/api/sdk/products/cm5abc123def456ghi789" \
  -H "X-PLASMA-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-PLASMA-Secret-Key: sk_live_xxxxxxxxxxxxxxxxxxxx"

Resposta

{
  "data": {
    "id": "cm5abc123def456ghi789",
    "deleted": true
  },
  "message": "Product deleted successfully"
}

Validações

RegraDescrição
Título obrigatórioMínimo 1, máximo 255 caracteres
Preço obrigatóriopriceCents deve ser inteiro ≥ 0
Compare at pricecompareAtPriceCents deve ser maior que priceCents
SKU únicoNão pode repetir na mesma loja (max 100 chars)
Máximo de imagens10 imagens por produto
DescriçãoMáximo 5000 caracteres

Erros Comuns

Código HTTPCódigoDescrição
400VALIDATION_ERRORCampo inválido ou obrigatório faltando
404NOT_FOUNDProduto não encontrado
409DUPLICATE_SKUSKU já existe na loja

Exemplo de Erro

{
  "error": "A product with this SKU already exists",
  "code": "DUPLICATE_SKU"
}

Webhooks Relacionados

EventoQuando é disparado
product.createdProduto criado, pelo painel ou pela API
product.updatedProduto alterado, pelo painel ou pela API (preço, estoque, variantes)
product.deletedProduto removido

Use esses avisos para revalidar o cache da sua vitrine. Com 60 requisições por minuto por chave, consultar o catálogo a cada visita estoura o limite no primeiro pico de tráfego.

Webhooks

Saiba mais sobre como receber notificações