# API: dados do produto (POST /product)

> Endpoint que retorna dados do produto (título, preço, imagem, moeda), o link de afiliado, o link final e o histórico de preços a partir de uma URL.

- URL: https://botdoafiliado.com/docs/api/product/
- Publicado em: 2026-05-29
- Atualizado em: 2026-10-21
- Índice da documentação para IA: https://botdoafiliado.com/llms.txt

Retorna **dados do produto**, o **link de afiliado**, o **link final** e o **histórico de preços** a partir de uma URL. O site/provider é detectado automaticamente.

- **Método:** `POST`
- **Path:** `/api/v1/product`
- **Auth:** header `X-API-Key`

A extração aceita o formato atual de produto do Magazine Você. Para Magalu e Terabyte, bloqueios no acesso direto podem usar uma segunda tentativa pelo proxy de extração. URLs de outras lojas com `/produto/` não são tratadas como produtos da KaBuM.

No Mercado Livre, anúncios sem catálogo também são identificados no destaque do link de afiliado, com sua variação. Os produtos da seção “Para você” não substituem o produto destacado.

## Request

```json
{
  "url": "https://shopee.com.br/...",
  "telegram_user_id": 123456789,
  "history_limit": 10,
  "watermark": true
}
```

- `url` (obrigatório): URL do produto.
- `telegram_user_id` (opcional): tracking/telemetria.
- `history_limit` (opcional): limite do histórico (1 a 50; padrão 10).
- `watermark` (opcional): `true` inclui `product.image_url_watermark`, a foto com a marca d'água configurada no painel (Configurar › Aparência das ofertas › Fotos e chamada › Marca d'água nas fotos). Vem `null` quando o produto não tem foto, a marca não está configurada ou a foto não pôde ser processada — o resto da resposta não muda.

## Response (200)

```json
{
  "success": true,
  "url_original": "https://shopee.com.br/...",
  "url_resolvida": "https://shopee.com.br/...",
  "affiliate_url": "https://...",
  "final_url": "https://...",
  "tracking_id": "....",
  "site": "shopee",
  "provider": "shopee",
  "product": {
    "title": "Nome do produto",
    "price": "199.90",
    "price_number": 199.9,
    "currency": "BRL",
    "image_url": "https://..."
  },
  "price_history": []
}
```

Campos de `product.*` podem vir `null` quando não foi possível extrair.

Pela API, o `price_history` vem sempre `[]`: o campo segue na resposta, mas o histórico de preço não tem acesso por API. Ele faz parte do módulo [Histórico de Preços](/modulos/historico-de-precos/) e aparece na vitrine e nas consultas feitas pelo Claude e pelo ChatGPT.

## Erros

- `401` — `{"success": false, "error": "invalid_api_key"}`
- `400` — `{"success": false, "error": "conversion_failed"}` (sem rota/conversor elegível)

Veja a tabela completa em **[erros e limites](/docs/api/erros-e-limites/)**.

## Preço anterior e parcelamento

O produto pode retornar `original_price` e seu alias `old_price` para o preço anterior, além de `installments`. Campos ausentes retornam `null`; o preço anterior só é válido quando maior que o preço atual.

```json
{
  "price": "199.90",
  "original_price": "299",
  "old_price": "299",
  "installments": { "count": 10, "amount": 19.99, "interest_free": true }
}
```

Os valores de `amount` e `total` são em reais. `interest_free` só aparece quando a fonte informa os juros. Não calcule parcelas dividindo o preço à vista: a condição do cartão pode ter outro total. A extração depende dos dados disponíveis no marketplace; a extensão também pode capturar a condição da página aberta pelo usuário.

## Perguntas frequentes

### No endpoint /product preciso informar o site ou provider do produto?

Não. O endpoint decide automaticamente o site/provider a partir da URL, com base nas rotas/conversores ativos do bot.

### O histórico de preços do produto sempre vem na resposta do /product?

Nem sempre. Pode vir vazio quando não há histórico. Use history_limit para limitar (1 a 50, padrão 10).

### Por que o endpoint /product retorna o erro conversion_failed?

Quando não há rota/conversor ativo que cubra a URL (ou faltam credenciais do provider). Não é erro de scraping.
