# Disputes API

> Read the disputes and chargebacks on your payments with the Anytime Capital Payments API: status, reason, amount, evidence deadline and evidence pack.

Source: https://anytime-capital.com/docs/disputes · Markdown: https://anytime-capital.com/docs/disputes.md · All docs: https://anytime-capital.com/docs/llms-full.txt

Disputes on your payments, as the **Disputes** page lists them. The API reads them; respond with evidence from **Disputes** in the dashboard before `evidenceDueAt`. The list's `nextCursor` is opaque: pass it back exactly as it came. Disputes can only be read, so a key's `disputes` access stops at read.

Each dispute carries its automatic evidence pack as `evidence`: whether it is built, how strong we read the case, whether we advise accepting, whether its PDF is attached to the response, and when it was or will be submitted. It is `null` when there is no pack. See [Dispute evidence](https://anytime-capital.com/docs/dispute-evidence.md) for what goes into a pack.

| Topic | Detail |
| --- | --- |
| Endpoints | [`GET /api/v1/disputes`](#list-disputes), [`GET /api/v1/disputes/{id}`](#get-dispute) |
| Key permissions | `disputes:read` |
| Samples | curl; Node.js 18+ with the built-in `fetch` (in an ES module); the [Node SDK](https://anytime-capital.com/docs/node-sdk.md) (preview: not on npm yet); Python with `requests`. |
| Every request can also answer | 401 `UNAUTHORIZED`, 401 `API_KEY_EXPIRED`, 403 `NOT_ENROLLED`, 403 `PERMISSION_DENIED`, 403 `IP_NOT_ALLOWED`, 429 `RATE_LIMITED`, 500 `INTERNAL_ERROR`. See [Error codes](https://anytime-capital.com/docs/error-codes.md). |

## The dispute object

```json
{
  "object": "dispute",
  "livemode": true,
  "id": "dspt_7Hq2LmX9cR4t",
  "paymentId": "pay_7Hq2LmX9cR4tVb",
  "amountCents": 12500,
  "currency": "usd",
  "status": "needs_response",
  "reason": "product_not_received",
  "inquiry": false,
  "customer": {
    "name": "Jordan Lee",
    "email": "jordan@example.com"
  },
  "card": {
    "brand": "visa",
    "last4": "4242"
  },
  "evidenceDueAt": "2026-11-01T23:59:59.000Z",
  "evidenceSubmittedAt": null,
  "createdAt": "2026-10-18T08:30:00.000Z",
  "evidence": {
    "status": "ready",
    "strength": "strong",
    "recommendAccept": false,
    "documentReady": true,
    "builtAt": "2026-10-18T08:31:12.000Z",
    "submittedAt": null,
    "autoSubmitAt": "2026-10-30T23:59:59.000Z"
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | The type of object. Always `dispute`. |
| `livemode` | boolean | False for test-mode data (an `ak_test_` key); true for live data. |
| `id` | string | `dspt_…` |
| `paymentId` | string | `pay_…` |
| `amountCents` | integer | Disputed. Integer cents. |
| `currency` | string | usd. |
| `status` | string | `needs_response` (respond before `evidenceDueAt`), `under_review`, then `won`, `lost` or `closed`. |
| `reason` | string | What the customer's bank gave as the reason: `fraudulent`, `unrecognized`, `declined_authorization`, `product_not_received`, `product_unacceptable`, `subscription_canceled`, `credit_not_processed`, `duplicate`, `processing_error`, `documentation_request`, `bank_cannot_process`, `other`. |
| `inquiry` | boolean | An inquiry or early warning rather than a chargeback. |
| `customer` | object |  |
| `customer.name` | string or null | Name. |
| `customer.email` | string or null | Email. |
| `card` | object or null |  |
| `card.brand` | string or null | Network. |
| `card.last4` | string or null | Last four. |
| `evidenceDueAt` | string (date-time) or null | Respond in the dashboard before this. |
| `evidenceSubmittedAt` | string (date-time) or null | Evidence submitted. |
| `createdAt` | string (date-time) | Opened. |
| `evidence` | object or null | The automatic evidence pack; null while there is none. |
| `evidence.status` | string | `building` (just opened, or rebuilding), `ready`, or `failed` (rebuild it from **Disputes**). |
| `evidence.strength` | string or null | `strong`, `fair` or `weak`: our read of the case once built, for you only. Never sent to the bank. |
| `evidence.recommendAccept` | boolean | Your own records back the customer: we advise accepting, and never submit it automatically. |
| `evidence.documentReady` | boolean | The pack's PDF, with the customer's receipt, is attached to the dispute response. |
| `evidence.builtAt` | string (date-time) or null | Built. |
| `evidence.submittedAt` | string (date-time) or null | Submitted with the pack, by your team or automatically. |
| `evidence.autoSubmitAt` | string (date-time) or null | When we'll submit the response for you: automatic submission is on, nobody has submitted, we don't advise accepting, and the deadline is still ahead. Otherwise `null`. |

## Endpoints

### List disputes

`GET /api/v1/disputes`

Permission: `disputes:read`.

Disputes on the business's payments, newest first. Respond in the dashboard. The cursor is opaque. Each dispute carries its automatic evidence pack as `evidence`: `building` right after the dispute opens, then `ready` (or `failed`), and `null` when there is none (automatic building is off and nobody has built one). See [Dispute evidence](https://anytime-capital.com/docs/dispute-evidence.md).

**Query**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string | no | Only disputes with this status. One of `needs_response`, `under_review`, `won`, `lost`, `closed`. |
| `limit` | integer | no | How many objects per page, 1–100. Default 25. See [Pagination](https://anytime-capital.com/docs/pagination.md). |
| `cursor` | string | no | The previous page's `nextCursor`, for the page after it. |

**Request (curl)**

```bash
curl "https://anytime-capital.com/api/v1/disputes?status=needs_response" \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/disputes?status=needs_response", {
  headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` },
});
const page = await res.json();
if (!res.ok) throw new Error(`${page.error.code}: ${page.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const page = await client.disputes.list({ status: "needs_response" });
```

**Request (Python)**

```python
import os

import requests

res = requests.get(
    "https://anytime-capital.com/api/v1/disputes",
    headers={"Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}"},
    params={"status": "needs_response"},
    timeout=30,
)
page = res.json()
if not res.ok:
    raise RuntimeError(f"{page['error']['code']}: {page['error']['message']}")
```

**Response** (200)

```json
{
  "object": "list",
  "data": [
    {
      "object": "dispute",
      "livemode": true,
      "id": "dspt_3Kw9PzR6tY2m",
      "paymentId": "pay_3Kw9PzR6tY2mQa",
      "amountCents": 4900,
      "currency": "usd",
      "status": "needs_response",
      "reason": "fraudulent",
      "inquiry": false,
      "customer": {
        "name": "Sam Ortiz",
        "email": "sam@example.com"
      },
      "card": {
        "brand": "mastercard",
        "last4": "4444"
      },
      "evidenceDueAt": "2026-11-08T23:59:59.000Z",
      "evidenceSubmittedAt": null,
      "createdAt": "2026-10-24T14:02:00.000Z",
      "evidence": {
        "status": "building",
        "strength": null,
        "recommendAccept": false,
        "documentReady": false,
        "builtAt": null,
        "submittedAt": null,
        "autoSubmitAt": null
      }
    },
    {
      "object": "dispute",
      "livemode": true,
      "id": "dspt_7Hq2LmX9cR4t",
      "paymentId": "pay_7Hq2LmX9cR4tVb",
      "amountCents": 12500,
      "currency": "usd",
      "status": "needs_response",
      "reason": "product_not_received",
      "inquiry": false,
      "customer": {
        "name": "Jordan Lee",
        "email": "jordan@example.com"
      },
      "card": {
        "brand": "visa",
        "last4": "4242"
      },
      "evidenceDueAt": "2026-11-01T23:59:59.000Z",
      "evidenceSubmittedAt": null,
      "createdAt": "2026-10-18T08:30:00.000Z",
      "evidence": {
        "status": "ready",
        "strength": "strong",
        "recommendAccept": false,
        "documentReady": true,
        "builtAt": "2026-10-18T08:31:12.000Z",
        "submittedAt": null,
        "autoSubmitAt": "2026-10-30T23:59:59.000Z"
      }
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
```

**Errors**

| Status | Code | When |
| --- | --- | --- |
| 400 | `INVALID_INPUT` | A field, filter, `limit` or `cursor` is missing or invalid. The message starts with the field's name, as in `amountCents: …`, or reads `Invalid cursor.` Fix the named field. Don't retry the same request unchanged. |
| 502 | `PROCESSOR_ERROR` | The payments network didn't answer in time. Retry with the same `Idempotency-Key`. A refund is keyed at the network by that key too, so a retry never refunds twice. |
| 503 | `NOT_CONFIGURED` | The part of Anytime Capital Payments this needs isn't available right now. Retry later, with the same `Idempotency-Key` on a write. |

### Get a dispute

`GET /api/v1/disputes/{id}`

Permission: `disputes:read`.

One dispute. `evidence.documentReady` is true once the pack's PDF is attached to the response, and `evidence.autoSubmitAt` says when we'll submit it for you (automatic submission on, nobody has submitted, and we don't advise accepting). `strength` and `recommendAccept` are our read of the case; neither is ever sent to the bank.

**Path**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | `dspt_…` |

**Request (curl)**

```bash
curl https://anytime-capital.com/api/v1/disputes/dspt_7Hq2LmX9cR4t \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/disputes/dspt_7Hq2LmX9cR4t", {
  headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` },
});
const dispute = await res.json();
if (!res.ok) throw new Error(`${dispute.error.code}: ${dispute.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const dispute = await client.disputes.retrieve("dspt_7Hq2LmX9cR4t");
```

**Request (Python)**

```python
import os

import requests

res = requests.get(
    "https://anytime-capital.com/api/v1/disputes/dspt_7Hq2LmX9cR4t",
    headers={"Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}"},
    timeout=30,
)
dispute = res.json()
if not res.ok:
    raise RuntimeError(f"{dispute['error']['code']}: {dispute['error']['message']}")
```

**Response** (200)

```json
{
  "object": "dispute",
  "livemode": true,
  "id": "dspt_7Hq2LmX9cR4t",
  "paymentId": "pay_7Hq2LmX9cR4tVb",
  "amountCents": 12500,
  "currency": "usd",
  "status": "needs_response",
  "reason": "product_not_received",
  "inquiry": false,
  "customer": {
    "name": "Jordan Lee",
    "email": "jordan@example.com"
  },
  "card": {
    "brand": "visa",
    "last4": "4242"
  },
  "evidenceDueAt": "2026-11-01T23:59:59.000Z",
  "evidenceSubmittedAt": null,
  "createdAt": "2026-10-18T08:30:00.000Z",
  "evidence": {
    "status": "ready",
    "strength": "strong",
    "recommendAccept": false,
    "documentReady": true,
    "builtAt": "2026-10-18T08:31:12.000Z",
    "submittedAt": null,
    "autoSubmitAt": "2026-10-30T23:59:59.000Z"
  }
}
```

**Errors**

| Status | Code | When |
| --- | --- | --- |
| 404 | `NOT_FOUND` | No such object on your business (an id from another business reads the same), or no such endpoint under `/api/v1`, which still answers in JSON. Check the id and the path. Ids are case-sensitive. |
| 502 | `PROCESSOR_ERROR` | The payments network didn't answer in time. Retry with the same `Idempotency-Key`. A refund is keyed at the network by that key too, so a retry never refunds twice. |
| 503 | `NOT_CONFIGURED` | The part of Anytime Capital Payments this needs isn't available right now. Retry later, with the same `Idempotency-Key` on a write. |

## Events

`dispute.opened` and `dispute.closed` carry the disputed [payment](https://anytime-capital.com/docs/payments.md) (its `dispute.status` says where it stands); `dispute.updated` carries the dispute itself when evidence is submitted or its status changes. See [Webhooks](https://anytime-capital.com/docs/webhooks.md) and [Fraud rules & 3D Secure](https://anytime-capital.com/docs/risk-and-3ds.md) for preventing them.

---

Anytime Capital is a fintech company, not a bank. Payment processing, banking and payout services are provided by Anytime Capital's licensed partners. Rates shown are for US card payments; international cards, currency conversion and disputes may carry additional fees shown in your dashboard before you accept a payment.
