Disputes - Special Return Mechanism (MED)
MED webhooks are active: you receive pix.med.opened and
pix.med.updated normally when a dispute is opened or changes status (see
Webhooks).
Every REST endpoint in the module — lookup
(GET /v1/accounts/{accountId}/pix/med), contestation (answer, decide,
evidence/*) and also the per-tenant listing and statistics
(/v1/backoffice/tenants/{tenantId}/meds and /med-stats) — returns
HTTP 503 with errorCode: "service_temporarily_unavailable" during the
settlement bank migration. The documentation below describes the contract for
those endpoints, which applies again once they are re-enabled.
MED (Mecanismo Especial de Devolucao) is the process by which a payer can request the return of a PIX payment, typically due to suspected fraud or operational error. When a MED is filed against your account, you have a deadline to contest or accept the return.
Lifecycle
OPEN -> PENDING_DECISION -> ACCEPTED / REJECTED / CANCELED
The webhook uses a closed vocabulary of five values in data.status. Raw
settlement bank statuses are never propagated: anything that does not match
the table below becomes PENDING_DECISION.
| Status | Description |
|---|---|
| OPEN | MED filed against your account. Awaiting a response within the deadline. |
| PENDING_DECISION | Response sent to the bank, awaiting regulator decision. Also used when the settlement bank sends a status outside the vocabulary. |
| ACCEPTED | MED accepted. The amount will be returned to the payer (total or partial). |
| REJECTED | MED rejected. The amount stays in your account. |
| CANCELED | MED canceled by the claimant or regulator. |
The CONTESTED state and the detailed history belong to the REST endpoints'
contract (currently returning 503) — they do not appear in webhooks.
Final Result
When a MED is closed, the result field indicates the banking partner outcome:
| Result | Description |
|---|---|
AGREED | Bank agreed with the return |
DISAGREED | Bank disagreed with the return |
Partial Refunds
A MED can result in multiple partial refunds. Each refund has its own E2E (D code) and amount. The refundedAmount field is the sum of all refunds made.
| Scenario | Example |
|---|---|
| Full refund | originalAmount: 1000.00, refundedAmount: 1000.00 |
| Partial refund | originalAmount: 1000.00, refundedAmount: 300.00 |
| No refund (no balance) | originalAmount: 1000.00, refundedAmount: 0.00 |
Receiving MEDs via Webhook
When a MED is filed, you receive a pix.med.opened webhook. When updated, pix.med.updated.
{
"id": "pix-med-opened-204cc938-da3d-4f04-baf3-0b2e6a2f1283",
"type": "pix.med.opened",
"occurredAt": "2026-02-18T19:34:14.000000000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-yourcompany",
"accountId": "773107de-...",
"data": {
"medId": "204cc938-da3d-4f04-baf3-0b2e6a2f1283",
"tenantId": "tenant-yourcompany",
"accountId": "773107de-...",
"originalEndToEnd": "E303062942026021812490000005QLMv",
"amount": 1000.00,
"reasonCode": "FRAUD",
"claimMessage": "I was scammed, did not receive the contracted product",
"openedAtIso": "2026-02-18T19:34:14.000000000Z",
"status": "OPEN"
}
}
pix.med.updated carries the same field set, without claimMessage and
openedAtIso, with status reflecting the transition.
Status History
The API maintains a complete history of all status changes. Each entry contains:
{
"history": [
{ "status": "RECEIVED", "rawStatus": "DELIVERED", "timestamp": "2026-02-18T19:34:14Z", "description": "MED received" },
{ "status": "CONTESTED", "rawStatus": "CONTESTED", "timestamp": "2026-02-19T10:00:00Z", "description": "Answer: DISAGREE" },
{ "status": "PENDING_DECISION", "rawStatus": "ACKNOWLEDGED", "timestamp": "2026-02-20T14:00:00Z" },
{ "status": "REJECTED", "rawStatus": "REJECTED", "timestamp": "2026-02-23T09:00:00Z" }
]
}
Contesting a MED
Contestation via API (submitting answers and uploading evidence) uses the
POST /v1/accounts/{accountId}/pix/med/{medId}/answer, /decide and
/evidence/* endpoints — all returning 503 today, as stated at the top of
this page. In the meantime, contestation must be done directly through the
banking partner's channel.
Looking up and Listing MEDs
Per account:
GET /v1/accounts/{accountId}/pix/med
Per tenant (backoffice):
GET /v1/backoffice/tenants/{tenantId}/meds
Once re-enabled, they return the MEDs with complete history, refunds, and control fields (holderAnswerStatus, holderAnswerDeadline, result).
MED Rate Monitoring
GET /v1/backoffice/tenants/{tenantId}/med-stats?days=30
Returns consolidated daily statistics:
| Field | Description |
|---|---|
pixInCount | PIX IN transactions on that day |
pixInAmount | Total PIX IN amount |
medCount | Number of MEDs for transactions of that day |
medAmount | Total MED amount |
quantityRatePercent | medCount / pixInCount * 100 |
amountRatePercent | medAmount / pixInAmount * 100 |
Reference Thresholds
The thresholds below are operational reference (used in the dashboard and in commercial follow-up), not API behaviour: no error code or block follows from them automatically. Automatic actions by rate are configured in Policies and Rules.
| Rate | Status | Description |
|---|---|---|
| < 0.4% | Healthy | Healthy rate |
| 0.4% - 1.0% | Yellow | Attention, monitor closely |
| > 1.0% | Red | Elevated rate, action may be required |
MED Policies
See the Policies and Rules guide for configuring:
- Auto-block: automatically hold the balance for MEDs above a given amount.
- Maximum rate: MED/PIX-In ratio limit with automatic actions.