> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onbeef.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Sincronize o catálogo

> Envie categorias, itens e ofertas.

Envie o catálogo completo ou uma atualização parcial. A API retorna `204` e processa o payload de forma assíncrona. Consulte o resultado em [`GET /v1/merchantStatus`](/api-reference/merchant/get-status).

<Note>
  Antes da primeira sincronização, registre a integração com [`PUT /v1/merchantOnboarding`](/api-reference/merchant/update-merchant).
</Note>

## Corpo da requisição

<ParamField body="merchantStatus" type="string" required>
  Disponibilidade da loja após a sincronização: `"AVAILABLE"` ou `"UNAVAILABLE"`.
</ParamField>

<ParamField body="entityType" type="string" required>
  Tipo de sincronização. Um dos valores:

  * `MERCHANT`: sincronização completa: categorias, itens e ofertas (o caso descrito nesta página).
  * `ITEM`: atualização apenas de itens (produtos).
  * `ITEM_OFFER`: atualização apenas de ofertas (preço e disponibilidade).
</ParamField>

<ParamField body="onlyAddProducts" type="boolean">
  Quando `true`, os produtos são adicionados sem desassociar os existentes das categorias. Quando `false` (ou omitido), a associação de produtos das categorias é substituída pelo conteúdo enviado.
</ParamField>

<ParamField body="updatedObjects" type="array" required>
  Array de objetos de merchant. Para `entityType: "MERCHANT"`, o primeiro objeto deve conter o `id` do merchant (seu identificador de loja no PDV) e as listas `categories`, `items` e `itemOffers`.

  <Expandable title="Campos de updatedObjects[]">
    <ParamField body="id" type="string" required>
      Identificador da sua loja no PDV. É armazenado como `pdv_external_id` do merchant.
    </ParamField>

    <ParamField body="categories" type="array">
      Categorias exibidas na vitrine. Cada categoria precisa de `id` e `name`; categorias sem esses campos são ignoradas.

      * `id` (string, obrigatório): UUID estável da categoria no seu PDV.
      * `name` (string, obrigatório): Nome de exibição.
      * `index` (integer): Ordem de exibição, começando em `0`.
      * `status` (string): `"AVAILABLE"` ou `"UNAVAILABLE"`.
      * `itemOfferId` (array of strings): IDs de `itemOffers` que pertencem a esta categoria.
    </ParamField>

    <ParamField body="items" type="array">
      Produtos referenciados pelas ofertas. Um item precisa de `name` para gerar um produto válido.

      * `id` (string): ID do item, referenciado por `itemOffer.itemId`.
      * `name` (string, obrigatório): Nome de exibição do produto.
      * `description` (string): Descrição do produto.
      * `externalCode` (string): Seu SKU ou código de referência interno.
      * `ean` (string): Código de barras EAN.
      * `unit` (string): `"KG"` (venda por peso) ou `"UN"` (venda por unidade).
      * `serving` (string): Sugestão de porção.
      * `nutritionalInfo` (object): Informações nutricionais, se houver.
      * `image` (object): Imagem do produto no formato `{ "url": "https://..." }`.
    </ParamField>

    <ParamField body="itemOffers" type="array">
      Ofertas de compra. Ligam um item a uma categoria e carregam preço e disponibilidade. Uma oferta precisa de `price.value` para gerar um produto válido.

      * `id` (string): ID da oferta, referenciado por `category.itemOfferId`.
      * `itemId` (string): ID do item ao qual esta oferta se refere.
      * `status` (string): `"AVAILABLE"` ou `"UNAVAILABLE"`.
      * `price` (object): Preço no formato `{ "value": 89.90 }`, em reais (BRL). O sistema usa `unit` do item para tratar o preço como por quilo (`KG`) ou por unidade (`UN`).
    </ParamField>
  </Expandable>
</ParamField>

<Info>
  Relação entre as entidades: a **categoria** referencia ofertas por `itemOfferId`; cada **itemOffer** aponta para um **item** por `itemId` e define o `price`. Uma oferta cujo item não tenha `name` ou cuja oferta não tenha `price.value` é descartada e reportada em `moreInfo` no `GET /v1/merchantStatus`.
</Info>

## Campos da resposta

### 204: Sem conteúdo

O catálogo foi recebido e enfileirado para processamento assíncrono. Consulte [`GET /v1/merchantStatus`](/api-reference/merchant/get-status) para confirmar `SUCCESS`.

### 401: Não autorizado

Token ausente ou inválido. Reautentique-se e tente novamente. Veja [Erros](/api-reference/errors).

## Exemplo

### Requisição

```bash theme={null}
curl -X PUT https://api.dev.connect.onbeefapp.com.br/v1/merchantUpdate \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  -H 'Content-Type: application/json' \
  -d '{
    "merchantStatus": "AVAILABLE",
    "entityType": "MERCHANT",
    "onlyAddProducts": false,
    "updatedObjects": [
      {
        "id": "9b2f4c1e-0a3d-4e8c-9d6a-2b7f1c0d5e3a",
        "categories": [
          {
            "id": "3f8a1b2c-4d5e-4f70-8192-a3b4c5d6e7f8",
            "name": "Carnes Bovinas",
            "index": 0,
            "status": "AVAILABLE",
            "itemOfferId": ["7c9e2f4a-1b3d-4e6f-8a90-b1c2d3e4f5a6"]
          }
        ],
        "items": [
          {
            "id": "5a6b7c8d-9e0f-4a2b-3c4d-5e6f7a8b9c0d",
            "name": "Picanha",
            "description": "Peça de picanha bovina, vendida por peso",
            "externalCode": "1001",
            "ean": "7891234567890",
            "unit": "KG",
            "image": { "url": "https://example.com/images/picanha.jpg" }
          }
        ],
        "itemOffers": [
          {
            "id": "7c9e2f4a-1b3d-4e6f-8a90-b1c2d3e4f5a6",
            "itemId": "5a6b7c8d-9e0f-4a2b-3c4d-5e6f7a8b9c0d",
            "status": "AVAILABLE",
            "price": { "value": 89.90 }
          }
        ]
      }
    ]
  }'
```

A API responde `204 No Content`. Em seguida, faça polling em `GET /v1/merchantStatus` até `status` ser `SUCCESS`.

<Warning>
  O processamento é assíncrono. Um `204` significa apenas que o payload foi aceito e enfileirado, não que o catálogo já está publicado. Confirme sempre com `GET /v1/merchantStatus`.
</Warning>

<Tip>
  Para ocultar temporariamente um produto sem removê-lo, defina o `status` do `itemOffer` correspondente como `"UNAVAILABLE"` em vez de omiti-lo do payload.
</Tip>
