DisputelyDocs

Alerts

List, inspect, and resolve dispute alerts.

An alert is a dispute warning. A cardholder has questioned a charge with their bank, and the card network told Disputely before opening a chargeback. Act on it in time and the chargeback never happens.

Alert types

TypeWhat it meansDo you act?
ETHOCAMastercard's alert network flagged a dispute or confirmed fraud.Yes — refund and resolve.
CDRNVerifi's (Visa) alert network flagged a dispute.Yes — refund and resolve.
RDRVisa auto-refunded the cardholder under your Rapid Dispute Resolution rules.No — informational. Reconcile the refund.

Lifecycle

Alerts arrive as NEEDS_REVIEW. For ETHOCA and CDRN alerts you have until respondBy (typically 48 hours) to act:

  • You refund the customer and call resolve → status: "RESOLVED". Done, no chargeback.
  • CANCELLED means the alert was declined (no refund issued) — the dispute will likely continue to a formal chargeback.

RDR alerts are already settled by Visa and can't be resolved through the API.


List alerts

GET /v1/alerts

Requires alerts:read. Returns your alerts, newest first.

curl "https://api.disputely.com/v1/alerts?status=NEEDS_REVIEW&limit=50" \
  -H "Authorization: Bearer dspm_live_YOUR_KEY"
ParamNotes
typeRDR, CDRN, or ETHOCA
statusNEEDS_REVIEW, RESOLVED, or CANCELLED
actionabletrue — shorthand for status=NEEDS_REVIEW and type CDRN/ETHOCA. Ideal for work queues.
createdSince / createdBeforeRFC 3339 timestamps
qSubstring match on paymentDescriptor (case-insensitive)
limitDefault 50, max 100
cursorFor pagination

Get an alert

GET /v1/alerts/{alertId}

Requires alerts:read. Returns 404 alert_not_found if the alert doesn't exist or isn't yours.

The alert object

{
  "id": "9XOJYR6WNLMU2XEQMSF244GFI",
  "accountId": "acct_2ZK8Q1M4",
  "type": "ETHOCA",
  "alertType": "dispute",
  "status": "NEEDS_REVIEW",
  "respondBy": "2026-10-02T18:30:00Z",
  "disputeAmount": 29.97,
  "disputeCurrency": "USD",
  "referenceTransactionAmount": 29.97,
  "referenceTransactionCurrency": "USD",
  "referenceTransactionDate": "2026-09-28T14:05:00Z",
  "authCode": "081224",
  "acquirerReferenceNumber": "74537604221234567890",
  "paymentType": "credit",
  "paymentDescriptor": "ACME*STORE",
  "paymentDescriptorContact": "8005551234",
  "networkDescriptor": null,
  "mcc": "5734",
  "reasonCode": "4837",
  "source": "mastercard",
  "caseDate": "2026-09-30",
  "timestamp": "2026-09-30T18:30:00Z",
  "networkTimestamp": "2026-09-30T18:29:41Z",
  "issuer": "CHASE BANK USA",
  "liability": "issuer",
  "merchantName": "ACME STORE",
  "transactionId": "MTF_1A2B3C4D",
  "age": 2,
  "respondedAt": null,
  "respondedBy": null,
  "refundedAmount": null,
  "refundedCurrency": null,
  "declineReason": null,
  "cardInfo": {
    "bin": "411111",
    "lastFour": "4242",
    "accountNumber": null
  }
}

Every field is always present (as null when unknown), so you can rely on key existence.

Fields you'll actually use

FieldMeaning
idAlert ID. Use it to fetch or resolve the alert.
type / statusSee tables above.
respondByDeadline to act. null on RDR.
disputeAmount / disputeCurrencyWhat the cardholder is disputing. Your refund can't exceed this.
paymentDescriptorThe billing descriptor the cardholder saw on their statement.
cardInfo.bin + cardInfo.lastFourFirst 6 + last 4 of the card — your main matching keys.
authCodeAuthorization code from the original transaction.
acquirerReferenceNumberARN — exact match key if your processor exposes it.
referenceTransactionDateWhen the original charge happened.
timestampWhen the alert reached Disputely.
reasonCodeNetwork reason code (e.g. 4837 = fraud, 4853 = cardholder dispute).

Matching tip: find the original order by cardInfo.bin + cardInfo.lastFour

  • amount + a date window around referenceTransactionDate. Use acquirerReferenceNumber or authCode for an exact match when available.

Resolve an alert

POST /v1/alerts/{alertId}/resolve

Requires alerts:write. Tells Disputely you refunded the cardholder — we synchronously notify the card network and the dispute is closed. Typical latency is 1–3 seconds.

curl -X POST "https://api.disputely.com/v1/alerts/9XOJYR6WNLMU2XEQMSF244GFI/resolve" \
  -H "Authorization: Bearer dspm_live_YOUR_KEY" \
  -H "Idempotency-Key: resolve-9XOJYR6WNLMU2XEQMSF244GFI" \
  -H "Content-Type: application/json" \
  -d '{ "refundedAmount": 29.97, "refundedCurrency": "USD" }'
FieldRequiredNotes
refundedAmountyesGreater than 0, at most disputeAmount. Equal = full refund, less = partial.
refundedCurrencyyesMust match disputeCurrency.

On success you get the updated alert back with status: "RESOLVED" and respondedAt / refundedAmount / refundedCurrency filled in.

Refund first, then resolve

Resolving tells the card network the cardholder got their money back. Issue the refund in your payment system before calling this endpoint.

Resolve errors

HTTPcodeMeaning
400invalid_refund_amountAmount is ≤ 0 or greater than disputeAmount.
400currency_mismatchrefundedCurrency doesn't match disputeCurrency.
404alert_not_foundAlert doesn't exist or isn't yours.
409alert_not_actionableRDR alert, or the alert was already declined.
422cannot_resolve_after_windowPast the respondBy deadline.
502provider_unavailableCard network timed out. Retry with the same Idempotency-Key.
502provider_rejectedCard network rejected the resolution — detail explains why.

Retries are safe. Resolving an alert that's already RESOLVED returns 200 with the current alert instead of an error. After a provider_unavailable, just retry with the same Idempotency-Key — the call converges on success.

On this page