# Mudanças de preços

> Mudanças de preço da lista e visualização de uma, incluindo o que o cliente pagará antes e depois.

Alterações em lote, agendamento e e-mails de mudanças de preço do cliente exigem Pro. Free pode publicar importações de planilhas de preço Standard imediatamente sem e-mails. Preços acordados existentes e mudanças agendadas publicadas continuam a se aplicar quando o Pro termina.

Os preços da lista nunca mudam silenciosamente no TradeCatalog. Novos preços entram em uma **mudança de preço** para uma lista de preços: um rascunho que os funcionários revisam, datam e publicam. Os clientes são enviados por e-mail apenas quando seus próprios preços mudam. Standard é a lista quando você não nomeia outra.

## Como as mudanças de preço são feitas

- **A partir da API:** [`PUT /products`](/docs/api/products#create-or-update-products) com um novo `listPrice` para um produto existente o adiciona a um rascunho e retorna o `priceChangeId` do rascunho.
- **A partir do app:** importações de planilhas, e alterações em lote como "+4% na categoria Parafusos".

A publicação, agendamento e cancelamento ocorrem no app, sob **Mudanças de preço**. Não há API para eles: uma pessoa sempre verifica uma mudança de preço antes que os clientes a vejam.

## Statuses

| Status      | Significado                                                |
| ----------- | ---------------------------------------------------------- |
| `draft`     | Não publicado. Nenhum preço mudou.                         |
| `scheduled` | Publicado com uma data futura. Os preços mudam nessa data. |
| `live`      | Em vigor.                                                  |
| `cancelled` | Cancelado antes que tivesse efeito.                        |

## O objeto de mudança de preço

```json
{
  "id": "c4d5e6f7-1234-4abc-9def-0123456789ab",
  "source": "import",
  "title": "API import (Sage stock sync)",
  "supplierNote": null,
  "status": "draft",
  "effectiveAt": null,
  "notifyCustomers": true,
  "raiseFixedPrices": false,
  "priceListId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "priceListName": "Standard",
  "createdBy": "Fq3L0cZ7tN1pW9aYx2Rk",
  "publishedAt": null,
  "cancelledAt": null,
  "createdAt": "2026-09-27T02:00:14.000Z",
  "items": 38
}
```

| Campo              | Tipo           | Descrição                                                                                                                      |
| ------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `source`           | string         | `import` (planilha ou API) ou `bulk` (uma mudança de porcentagem feita no app).                                                |
| `title`            | string         | Mostrado aos funcionários. Os rascunhos da API têm o título "Importação da API (nome da chave)".                               |
| `supplierNote`     | string ou nulo | Mensagem aos clientes no e-mail de mudança de preço.                                                                           |
| `status`           | string         | Veja [status](#statuses).                                                                                                      |
| `effectiveAt`      | string ou nulo | Quando os novos preços se aplicam.                                                                                             |
| `notifyCustomers`  | booleano       | Se os clientes são enviados por e-mail com seus novos preços.                                                                  |
| `raiseFixedPrices` | booleano       | Se os preços acordados aumentam na mesma porcentagem. Essa escolha é separada da lista.                                        |
| `priceListId`      | string ou nulo | A lista em que essa mudança é escrita. Nulo significa Standard, incluindo mudanças feitas antes que as listas fossem nomeadas. |
| `priceListName`    | string         | O nome dessa lista. `Standard` quando `priceListId` é nulo.                                                                    |
| `createdBy`        | string ou nulo | Id da pessoa que o fez. Para rascunhos da API, a pessoa que criou a chave.                                                     |
| `items`            | inteiro        | Quantos produtos ele muda. Apenas na lista.                                                                                    |

## Mudanças de preço da lista

**GET** `/api/v1/price-changes`

Mais recentes primeiro. Cobre as **100 mudanças de preço mais recentes**.

| Nome     | Tipo    | Obrigatório | Descrição                 |
| -------- | ------- | ----------- | ------------------------- |
| `limit`  | inteiro | não         | 1 a 100. Padrão 100.      |
| `offset` | inteiro | não         | Linhas a pular. Padrão 0. |

```bash
curl https://tradecatalog.app/api/v1/price-changes \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
```

```js
const res = await fetch('https://tradecatalog.app/api/v1/price-changes', {
  headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: changes } = await res.json()
const drafts = changes.filter((change) => change.status === 'draft')
```

## Visualizar uma mudança de preço

**GET** `/api/v1/price-changes/{id}`

Tudo o que os funcionários veem antes da publicação: quantos preços sobem e descem, as maiores mudanças, alertas e quantos preços acordados ela afeta. Passe `customer` para ver os preços próprios do cliente antes e depois.

| Nome       | Em       | Tipo   | Obrigatório | Descrição                         |
| ---------- | -------- | ------ | ----------- | --------------------------------- |
| `id`       | caminho  | string | sim         | Id da mudança de preço.           |
| `customer` | consulta | string | não         | Id do cliente ou código da conta. |

```bash
curl "https://tradecatalog.app/api/v1/price-changes/c4d5e6f7-1234-4abc-9def-0123456789ab?customer=OAK01" \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
```

```js
const res = await fetch(
  `https://tradecatalog.app/api/v1/price-changes/${priceChangeId}?customer=OAK01`,
  { headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` } },
)
const { data: preview } = await res.json()
if (preview.warnings.length)
  console.warn('Check these before publishing', preview.warnings)
```

```json
{
  "data": {
    "change": {
      "id": "c4d5e6f7-1234-4abc-9def-0123456789ab",
      "source": "import",
      "title": "API import (Sage stock sync)",
      "supplierNote": null,
      "status": "draft",
      "effectiveAt": null,
      "notifyCustomers": true,
      "raiseFixedPrices": false,
      "priceListId": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
      "priceListName": "Standard",
      "createdBy": "Fq3L0cZ7tN1pW9aYx2Rk",
      "publishedAt": null,
      "cancelledAt": null,
      "createdAt": "2026-09-27T02:00:14.000Z"
    },
    "counts": { "total": 38, "up": 36, "down": 2 },
    "biggest": [
      {
        "productId": "3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c",
        "oldPrice": 1850,
        "newPrice": 1950,
        "sku": "HX-8510",
        "name": "Hex bolt M10 x 50 zinc",
        "changeBp": 541
      }
    ],
    "warnings": [],
    "fixedAffected": 3,
    "customer": {
      "name": "Oakfield Joinery",
      "rows": [
        {
          "sku": "HX-8510",
          "name": "Hex bolt M10 x 50 zinc",
          "before": 1573,
          "after": 1658,
          "label": "Brand discount −15%"
        }
      ]
    }
  },
  "currency": "GBP"
}
```

| Campo           | Descrição                                                                                                                                                                                                      |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `counts`        | Produtos na mudança, e quantos sobem e descem.                                                                                                                                                                 |
| `biggest`       | Até 20 itens com a maior variação percentual. `changeBp` é a variação em pontos básicos (541 = +5,41%).                                                                                                        |
| `warnings`      | Itens que variam mais de 30% para cima ou para baixo, ou vão para zero. Normalmente erros de digitação.                                                                                                        |
| `fixedAffected` | Preços acordados nesses produtos que são válidos agora. Eles só mudam se a mudança aumentar os preços acordados.                                                                                               |
| `customer`      | Com `customer`: os preços unitários desse cliente antes e depois, da sua própria lista e depois da sua ajuste, para até os primeiros 50 itens. Um cliente em outra lista permanece inalterado. `null` sem ele. |

`404 not_found` se não houver essa mudança de preço neste workspace.
