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

# Contestações Pix (MED)

> Entenda o MED, acompanhe contestações de Pix pela API e por webhook, e saiba o que acontece com o valor retido em cada situação.

O MED (Mecanismo Especial de Devolução) é o procedimento do Pix pelo qual um pagador contesta um pagamento, por exemplo por suspeita de fraude ou golpe. Enquanto a contestação é analisada, o valor contestado fica **retido**.

Para você que integra, o MED importa por um motivo: um Pix aprovado há dias pode ter o valor retido depois. A API deixa você saber disso na hora, sem esperar o saldo bater diferente.

<Note>
  Na API, o MED é **somente leitura**. Quem abre e decide a contestação é a NyxPag junto à processadora. Você consulta e recebe webhooks, mas não cria nem decide.
</Note>

## O ciclo de uma contestação

```mermaid theme={"dark"}
stateDiagram-v2
    [*] --> pending: pagador contesta, valor retido
    pending --> approved: contestação aceita
    pending --> rejected: contestação negada, valor liberado
    pending --> cancelled
```

O status `closed` indica uma contestação encerrada. Trate-o como estado final.

| Status | O que significa | Efeito no seu dinheiro |
| - | - | - |
| `pending` | Em análise | Valor **retido**. Não conte como disponível |
| `approved` | O pagador teve razão | O valor não volta para a sua conta |
| `rejected` | A contestação foi negada | O valor retido é **liberado** para a sua conta |
| `cancelled` | A contestação foi cancelada | Confira o estado em `GET /meds/{id}` e o saldo em `GET /balance` |
| `closed` | Encerrada | Registre e confira o saldo |

<Warning>
  `approved` não quer dizer que **você** foi aprovado. Quer dizer que o pedido do **pagador** foi aceito. É a confusão mais comum ao tratar esse status.
</Warning>

## Listar contestações

`GET /meds` retorna só as contestações da conta autenticada, ordenadas pela atualização mais recente. Exige a permissão `transactions:read`.

| Parâmetro | Tipo | Descrição |
| - | - | - |
| `page` | integer | Página, a partir de 1 |
| `limit` | integer | Itens por página, de 1 a 100. Padrão 20 |
| `status` | string | `pending`, `approved`, `rejected`, `cancelled` ou `closed` |

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl "https://api.nyxpag.com.br/v1/meds?status=pending&limit=20" \
    -H "Authorization: Bearer $NYXPAG_API_KEY"
  ```

  ```javascript JavaScript theme={"dark"}
  const res = await fetch("https://api.nyxpag.com.br/v1/meds?status=pending&limit=20", {
    headers: { Authorization: `Bearer ${process.env.NYXPAG_API_KEY}` },
  });
  const { data, pagination } = await res.json();
  console.log(data.length, pagination.total);
  ```

  ```python Python theme={"dark"}
  import os
  import requests

  res = requests.get(
      "https://api.nyxpag.com.br/v1/meds",
      params={"status": "pending", "limit": 20},
      headers={"Authorization": f"Bearer {os.environ['NYXPAG_API_KEY']}"},
      timeout=15,
  )
  body = res.json()
  print(len(body["data"]), body["pagination"]["total"])
  ```

  ```php PHP theme={"dark"}
  <?php
  $ch = curl_init('https://api.nyxpag.com.br/v1/meds?status=pending&limit=20');
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NYXPAG_API_KEY')],
  ]);
  $body = json_decode(curl_exec($ch), true);
  echo count($body['data']) . ' / ' . $body['pagination']['total'];
  ```
</CodeGroup>

```json theme={"dark"}
{
  "success": true,
  "data": [
    {
      "id": "med_01JABCDEF0123456789",
      "status": "pending",
      "amount": 149.9,
      "currency": "BRL",
      "transactionId": "txn_mabc123_0123456789abcdef",
      "orderId": "PEDIDO-1042",
      "reason": "Contestação MED registrada pela NyxPag.",
      "createdAt": "2026-10-03T16:20:00.000Z",
      "updatedAt": "2026-10-03T16:20:00.000Z",
      "resolvedAt": null
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 1, "pages": 1 },
  "requestId": "req_01H..."
}
```

Um `status` fora da lista retorna `400` com `error.code: "invalid_med_status"`.

## Consultar uma contestação

`GET /meds/{id}` aceita três identificadores, o que evita você guardar mais um ID:

* o **ID do MED** (`med_...`);
* o **ID da transação** NyxPag (`txn_...`);
* o **`externalId`** do pedido, o mesmo que você enviou ao criar a cobrança.

```bash theme={"dark"}
curl "https://api.nyxpag.com.br/v1/meds/PEDIDO-1042" \
  -H "Authorization: Bearer $NYXPAG_API_KEY"
```

Se não existir contestação para o identificador, a resposta é `404` com `error.code: "not_found"`.

## Receber por webhook

Os eventos `med.created` e `med.updated` chegam no mesmo endpoint dos eventos de transação, com a mesma assinatura.

<Card title="Eventos de MED" icon="webhook" href="/webhooks/med">
  Payload completo, campos e um receptor pronto.
</Card>

## Como lidar na prática

<Steps>
  <Step title="Marque o pedido ao abrir">
    Em `med.created`, sinalize o pedido (`orderId`) como em disputa e pare de contar o valor como disponível.
  </Step>

  <Step title="Aguarde a decisão">
    Em `med.updated`, olhe `data.status`. `rejected` libera o valor. `approved` confirma a perda.
  </Step>

  <Step title="Concilie com a lista">
    Um job diário em `GET /meds?status=pending` cobre qualquer webhook que não chegou.
  </Step>

  <Step title="Confira o saldo">
    Depois de cada decisão, compare com `GET /balance`. Veja [Consultar saldo](/guides/pix/saldo).
  </Step>
</Steps>

<CardGroup cols={2}>
  <Card title="Listar contestações MED" icon="code" href="/api-reference/med/listar-contestações-med">
    Referência do endpoint GET /meds.
  </Card>

  <Card title="Consultar uma contestação" icon="code" href="/api-reference/med/consultar-uma-contestação-med">
    Referência do endpoint GET /meds/{id}.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.