Creates a move to transfer funds between two subaccounts within the same root entity.
**Request Headers**
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| `Idempotency-Key` | String | No | Unique key to prevent duplicate move requests. If provided, the same key cannot be used for another move. |
**Request Body**
| Field | Type | Required | Default | Description | Validation Rules |
|----------------------|------|----------|---------|-------------|-----------------|
| `from_subaccount_id` | UUID | Yes | — | ID of the subaccount to move funds from. | Must be a valid UUID for an existing subaccount owned by your root entity |
| `to_subaccount_id` | UUID | Yes | — | ID of the subaccount to move funds to. | Must be a valid UUID for an existing subaccount owned by your root entity, different from `from_subaccount_id` |
| `amount_in_minor_units` | Integer | Yes | — | Amount to move in the smallest unit of the currency. For USD, this is cents (100 = $1.00). | Must be a positive whole number. |
| `auto_approve` | Boolean | No | `true` | Whether to automatically approve and settle the move. When `false`, the move is created in `created` status and must be approved separately. | — |
| `client_metadata` | Object | No | — | Optional client key-value metadata to store with the move for your own reference. | Must be an object with string keys and string values. Maximum 50 keys, each key max 40 characters, each value max 500 characters, total size max 16KB. |
**Examples:**
- For USD, `amount_in_minor_units: 1000` is 1000 cents = $10.00
- For USD, `amount_in_minor_units: 1250` is 1250 cents = $12.50
**Approval flow**
When `auto_approve` is `true` (default), the move is created, approved, and settled in one request — the response has `status: "settled"`.
When `auto_approve` is `false`, the move is created in `created` status. Use **`POST /api/subaccounts/move/{move_id}/approve`** to approve and settle it, or **`DELETE /api/subaccounts/move/{move_id}`** to cancel it.
Moves do not enforce a minimum source balance — a subaccount may show a negative available balance after settlement.
**Response Body**
| Field | Type | Description |
|-------|------|-------------|
| `id` | UUID | Unique identifier for the move. |
| `from_subaccount_id` | UUID | ID of the subaccount funds were moved from. |
| `to_subaccount_id` | UUID | ID of the subaccount funds were moved to. |
| `amount_in_minor_units` | Integer | The move amount in the smallest unit of the currency. For USD, cents (100 = $1.00). |
| `status` | String | Current status of the move (`created`, `approved`, `settled`, `canceled`). |
| `status_recorded_at` | DateTime | Timestamp of the latest status change. |
| `client_metadata` | Object | Arbitrary metadata as key-value pairs that were provided when creating the move |
| `created_at` | DateTime | Timestamp when the move was created. |
| `updated_at` | DateTime | Timestamp when the move was last updated. |
**Idempotency Key**
You can include an `Idempotency-Key` header to ensure that duplicate requests are handled safely. When you retry a request with the same idempotency key:
- **200 OK**: If a move with the same idempotency key already exists and no further work is needed for this request, the existing move is returned.
- **201 Created**: If no move exists with the provided idempotency key, a new move is created.
- With **`auto_approve=true`** (the default), an idempotency match that is still **`CREATED`** continues approve→settle. A match in **`CANCELED`** or **`FAILED`** returns **409**.
**Success Responses**
| Status Code | Description |
|-------------|-------------|
| 200 | OK — An existing move with the provided idempotency key was found and returned (idempotency recovery / already-advanced replay). |
| 201 | Created — The move was successfully created (and settled, if `auto_approve` is `true`). |
| 207 | Multi-Status — The move was created and `auto_approve` was requested, but approval or settlement encountered an error. See `warning` in the response body. |
**Error Responses**
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | VALIDATION_ERROR | The provided data failed validation (e.g., invalid UUIDs, same from/to subaccount, negative amount). |
| 401 | AUTHENTICATION_ERROR | Authentication credentials are invalid or missing. |
| 403 | AUTHORIZATION_ERROR | You do not have permission to perform this action. |
| 404 | NOT_FOUND | One or both subaccounts were not found. |
| 409 | IDEMPOTENCY_KEY_CONFLICT | Idempotency key matches an existing move in a terminal failed or canceled state; use a new key. |
Request
This endpoint expects an object.
from_subaccount_idstringRequired
ID of the subaccount to move funds from
to_subaccount_idstringRequired
ID of the subaccount to move funds to
amount_in_minor_unitsinteger or nullOptional
Amount to move in the account currency’s minor units (e.g. cents for USD).
auto_approvebooleanOptionalDefaults to true
Whether to automatically approve and settle the move. When false, the move is created in CREATED status and must be approved separately.
client_metadatamap from strings to strings or nullOptional
Optional client key-value metadata stored as client_metadata.
amount_in_centsinteger or nullOptionalDeprecated
Deprecated. Use amount_in_minor_units instead. Still accepted and returned for backward compatibility.