# Create a refund

`POST /accounts/{accountID}/transfers/{transferID}/refunds`

API version: `v2026.10.00`. Send `X-Moov-Version: v2026.10.00` to get the behavior described here.

> AI agents: search and read all Moov docs with the docs MCP server at https://docs.moov.io/mcp (no API key). Setup: https://docs.moov.io/guides/developer-tools/mcp-ai/docs-mcp/index.md

Initiate a refund for a card transfer.
The `accountID` must identify the partner account for the transfer.

**Use the [Cancel or refund a card transfer](https://docs.moov.io/api/money-movement/refunds/cancel/) endpoint for more comprehensive cancel and refund options.**    
See the [reversals](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/) guide for more information. 

To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/) 
you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `X-Moov-Version` | header | string |  | Set this header to v2026.10.00 to use the API described in this specification. When omitted, the server defaults to v2024.01.00, the earliest supported version, which may not match the behavior documented here. An unrecognized well-formed version uses the latest supported version that is not newer than the requested version, when one exists. For example, `v2026.08.00` uses `v2026.07.00`. A malformed value, such as `2022`, returns a `404` response. Values: `v2026.10.00`. |
| `x-idempotency-key` | header | string | Yes | Prevents duplicate refunds from being created. |
| `x-wait-for` | header | string |  | Optional header that indicates whether to return a synchronous response that includes full transfer and rail-specific details or an asynchronous response indicating the transfer was created (this is the default response if the header is omitted). A timeout will occur after 15 seconds. Values: `rail-response`. |
| `accountID` | path | string | Yes | Moov account ID of the partner for the transfer. |
| `transferID` | path | string | Yes | Identifier for the transfer. |

## Request body

Content type: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | object |  | Amount to refund. If omitted, the original transfer's full amount will be refunded. |
| `amount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `amount.valueDecimal` | string | Yes | A decimal-formatted numerical string that represents up to 9 decimal place precision. For example, $12.987654321 is '12.987654321'. |
| `captureID` | string |  | ID of the capture to refund. This field is only relevant for an auth-capture `card-payment` transfer. |
| `amountDetails` | object |  | Breakdown of the refunded amount. |
| `amountDetails.surcharge` | object |  | The amount of surcharge to refund. Should be proportionate to the surcharge on the original transfer |
| `amountDetails.surcharge.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `amountDetails.surcharge.valueDecimal` | string | Yes | A decimal-formatted numerical string that represents up to 9 decimal place precision. For example, $12.987654321 is '12.987654321'. |

## Response 200

The request completed successfully.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `refundID` | string |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. Identifier for the refund. |
| `createdOn` | string (date-time) |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. |
| `updatedOn` | string (date-time) |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. |
| `status` | string |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. Values: `created`, `pending`, `completed`, `failed`. |
| `amount` | object |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. |
| `amount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `amount.valueDecimal` | string | Yes | A decimal-formatted numerical string that represents up to 9 decimal place precision. For example, $12.987654321 is '12.987654321'. |
| `captureID` | string |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. ID of the capture refunded for an auth-capture `card-payment` transfer. |
| `amountDetails` | object |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. |
| `amountDetails.surcharge` | object |  | The amount of surcharge to refund. Should be proportionate to the surcharge on the original transfer |
| `processingDetails` | object |  | Send exactly one of `refundID`, `createdOn`, `updatedOn`, `status`, `amount`, `captureID`, `amountDetails`, `processingDetails`. |
| `processingDetails.cardPayment` | object |  |  |

## Response 202

A refund was successfully created but an error occurred while waiting for a synchronous response.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `refundID` | string | Yes | Identifier for the refund. |
| `createdOn` | string (date-time) | Yes |  |
| `updatedOn` | string (date-time) | Yes |  |
| `status` | string | Yes | Values: `created`, `pending`, `completed`, `failed`. |
| `amount` | object | Yes |  |
| `amount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `amount.valueDecimal` | string | Yes | A decimal-formatted numerical string that represents up to 9 decimal place precision. For example, $12.987654321 is '12.987654321'. |
| `captureID` | string |  | ID of the capture refunded for an auth-capture `card-payment` transfer. |
| `amountDetails` | object |  |  |
| `amountDetails.surcharge` | object |  | The amount of surcharge to refund. Should be proportionate to the surcharge on the original transfer |
| `processingDetails` | object | Yes |  |
| `processingDetails.cardPayment` | object |  |  |

## Errors

| Status | Meaning |
| --- | --- |
| 400 | The server could not understand the request due to invalid syntax. |
| 404 | The requested resource was not found. |
| 409 | Attempted to create a refund using a duplicate X-Idempotency-Key header. The body is the same as the 202 response. |
| 422 | The request was well-formed, but the contents failed validation. Check the request for missing or invalid fields. |
| 429 | Request was refused due to rate limiting. |
| 500 | The request failed due to an unexpected error. |
| 504 | The request failed because a downstream service failed to respond. |

## Examples

### cURL

```bash
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/refunds" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.10.00" \
  -H "X-Idempotency-Key: 7d8f2a64-4b1e-4c3a-9f2d-1e5b6c7a8d90"
```

### Typescript (SDK)

```typescript
import { Moov } from "@moovio/sdk";

const moov = new Moov({
  security: {
    username: "",
    password: "",
  },
});

async function run() {
  const result = await moov.transfers.initiateRefund({
    xIdempotencyKey: "8d9af6b8-67e1-4efa-8188-68039f34097d",
    accountID: "cb6ae9f9-afab-4f06-9eb0-8abf54a3ada2",
    transferID: "04022119-95be-4ef4-9dd4-b3782f6aa7b9",
    createRefund: {
      amount: {
        currency: "USD",
        valueDecimal: "12.987654321",
      },
      amountDetails: {
        surcharge: {
          currency: "USD",
          valueDecimal: "12.987654321",
        },
      },
    },
  });

  console.log(result);
}

run();
```

Full reference with SDK examples in every language: https://docs.moov.io/api/v2026.10.00/money-movement/refunds/create/
