> This page is for version v1 (default).
> For other versions, use one of these documentation indexes:
> - v1 (default): https://developers.truemed.com/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.truemed.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.truemed.com/_mcp/server.

# Respond with evidence

> How to draft, autosave, and submit dispute evidence through the counter lifecycle.

To contest a chargeback you build a **counter** — your evidence response for one dispute phase. You compose it as a draft
(continuously autosaved), then submit it to the processor in a single, final action.

> **Warning**
>
> **Submission is one-shot and irreversible.** Card disputes allow exactly one evidence response per phase — there is no
> within-phase back-and-forth with the issuer. Once you submit, the counter is locked and goes straight to the processor.
> Get the draft right before you submit it.

## The counter lifecycle

A counter moves through these states:

| State        | Meaning                                                                              |
| ------------ | ------------------------------------------------------------------------------------ |
| `draft`      | Editable. Autosaved as you compose. At most one draft exists per dispute phase.      |
| `submitted`  | Sent to the processor. Terminal for this phase.                                      |
| `withdrawn`  | A draft you discarded.                                                               |
| `superseded` | A prior phase's submission, replaced when a new phase (e.g. pre-arbitration) opened. |

A dispute usually has **exactly one** counter. A new counter is created only when a new phase/round opens: the dispute
re-enters `needs_response` at a higher phase, a fresh `draft` is created, and the previous `submitted` counter becomes
`superseded`. In practice, multi-phase rounds are rare.

## Evidence categories

Evidence is a list of `evidence_items`, each tagging a **canonical category** with free `text` and/or attached
`file_ids`. Truemed maps these categories to the processor for you, so you provide evidence in one canonical form.
Categories:

`product_description`, `customer_communication`, `customer_name`, `customer_email`, `customer_purchase_ip`,
`customer_signature`, `billing_address`, `receipt`, `shipping_documentation`, `shipping_tracking_number`,
`service_documentation`, `service_date`, `access_activity_log`, `refund_policy`, `refund_policy_disclosure`,
`refund_refusal_explanation`, `cancellation_policy`, `cancellation_policy_disclosure`, `cancellation_rebuttal`,
`duplicate_charge_documentation`, `duplicate_charge_explanation`, `uncategorized`.

The dispute's `evidence_requirements` (from the [detail endpoint](/guides/setup/api/disputes/list-and-retrieve) or the `dispute.*`
webhook) resolves the recommended evidence for the dispute's `reason`, already grouped by weight: lead with the
`compelling` categories, then add `supporting`; `other` lists the remaining categories the processor accepts. Each entry
tells you whether it takes free `text` and/or a `file`, and `merchant_explanation` is Truemed's narrative on how to
contest this reason. For example, a `product_not_received` dispute surfaces `shipping_tracking_number` and
`service_documentation` as compelling, while `product_unacceptable` surfaces `product_description` and your
`refund_policy_disclosure`. Provide the categories that best rebut the specific reason.

## 1. Create a draft

`POST /api/v1/disputes/{dispute_id}/counters` creates the draft. You may seed it with initial evidence or start empty.

```bash
curl -s -X POST "https://dev-api.truemed.com/api/v1/disputes/$DISPUTE_ID/counters" \
  -H "Authorization: Bearer $TRUEMED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "evidence_items": [
      {"category": "product_description", "text": "Organic magnesium supplement, 60ct."}
    ]
  }'
```

The response is the counter, including its `counter_id` and `revision` (starts at the first revision). Persist both.

## 2. Autosave the draft

`POST /api/v1/disputes/{dispute_id}/counters/{counter_id}` upserts the draft. It's a **full replacement** of
`evidence_items` and is built for autosave. There's no fixed rate limit, but debounce saves to roughly one every
**300–500 ms** of idle typing rather than firing on every keystroke — enough to feel live without redundant writes.

Autosave validates the evidence shape (category capabilities, one file per category, no duplicate categories) and
rejects an invalid save with `422` — the persisted draft is left untouched. Empty or partially-filled items (a category
with no text or file yet) save fine, so an in-progress draft is never blocked; surface the `422` inline and keep the
merchant's edits rather than discarding them.

To stay safe under concurrent editors, the draft is **optimistically locked**: send the `revision` you last read. If the
counter changed since (another editor saved first), the request is rejected with `409 Conflict` — reload the counter and
retry with the new revision.

```bash
curl -s -X POST "https://dev-api.truemed.com/api/v1/disputes/$DISPUTE_ID/counters/$COUNTER_ID" \
  -H "Authorization: Bearer $TRUEMED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "revision": 1,
    "evidence_items": [
      {"category": "product_description", "text": "Organic magnesium supplement, 60ct."},
      {"category": "shipping_tracking_number", "text": "1Z999AA10123456784"},
      {"category": "receipt", "file_ids": ["f47ac10b-58cc-4372-a567-0e02b2c3d479"]}
    ]
  }'
```

> **Info**
>
> Evidence is saved server-side only — there is no client-side draft store — because dispute evidence can contain PHI.

## 3. Submit (one-shot)

`POST /api/v1/disputes/{dispute_id}/counters/{counter_id}/submit` submits your evidence to the processor. The counter
moves to `submitted`.

```bash
curl -s -X POST "https://dev-api.truemed.com/api/v1/disputes/$DISPUTE_ID/counters/$COUNTER_ID/submit" \
  -H "Authorization: Bearer $TRUEMED_API_KEY"
```

The dispute does **not** flip to `under_review` synchronously — that transition is driven by the resulting processor
webhook. Watch for [`dispute.updated`](/guides/setup/api/disputes/webhooks) and re-fetch the dispute for authoritative state.

## Withdraw a draft

`POST /api/v1/disputes/{dispute_id}/counters/{counter_id}/withdraw` discards a `draft` you no longer want. Only drafts can
be withdrawn — a submitted counter is permanent.

## Error responses

| Status                     | When                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `409 Conflict`             | The `revision` you sent is stale — another save landed first. Reload and retry.                                                                                                                                                                                                                                                                                                                                                                              |
| `422 Unprocessable Entity` | Evidence validation failed. This is checked on **create and autosave**, not only at submit, so an invalid draft is never persisted. Causes: a `file_id` you don't own (see [Upload Evidence Files](/guides/setup/api/disputes/upload-evidence-files)); free text on a file-only category (or a file on a text-only category); more than one file on a category; or two items sharing a category. The whole request is rejected; nothing is silently dropped. |
| `400 Bad Request`          | The counter isn't editable (not a draft), or the dispute can't accept a submission right now.                                                                                                                                                                                                                                                                                                                                                                |
| `404 Not Found`            | The dispute or counter isn't on your sales channel.                                                                                                                                                                                                                                                                                                                                                                                                          |