Move funds between subaccounts

View as Markdown
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, the existing move is returned. This allows you to recover the move ID after transient errors (e.g., 500 Internal Server Error). - **201 Created**: If no move exists with the provided idempotency key, a new move is created. **Success Responses** | Status Code | Description | |-------------|-------------| | 200 | OK — An existing move with the provided idempotency key was found and returned (idempotency retry scenario). | | 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. |

Authentication

x-api-keystring

RootPay API key sent in the x-api-key header. Keys are environment-scoped: live_* for production, test_* for sandbox.

Headers

Idempotency-Keystring or nullOptional
Unique key to prevent duplicate requests

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.

Response

Move retrieved successfully (idempotency retry)