---
search:
  tags:
    - Portfolio
    - POST
seo:
  description: >-
    Transfers cash between two of the caller's accounts, atomically. The caller
    must be… Reference for the POST /portfolio/transfers endpoint in the REST
    API API.
sidebar:
  badge: POST
  label: Transfer Between Accounts
title: Transfer Between Accounts
type: openapi-operation
---
Transfers cash between two of the caller's accounts, atomically. The caller must be authorized to act on both accounts, and both always belong to the caller's member. An API key must be unrestricted and carry the `transfer` scope; an account-restricted key cannot transfer, because a transfer always spans two accounts. Rejected if it would overdraw the source account, if the amount is zero, or if the source and destination are the same account. An unknown account, or one the caller cannot use, answers the same 400 as any invalid parameter.

### Endpoint

- Method and path: `POST /portfolio/transfers`
- Operation ID: `transferBetweenAccounts`
- API reference: [POST /portfolio/transfers](/api-reference/portfolio/transferbetweenaccounts)

#### Authorization

- Accepted credentials: `UDX-Access-Key` header and `UDX-Access-Timestamp` header and `UDX-Access-Signature` header; or Bearer token in `Authorization`
- Details: [Authentication](/authentication)

#### Parameters

- `UDX-Version` (`header`) — Dated API version (YYYY-MM-DD). Omit to use the oldest supported version. An unknown version returns `400`.
- `UDX-Idempotency-Key` (`header`) — Optional client-generated key that makes a mutation safe to retry. Reuse it only for a byte-identical retry. When present, it is included in the request signature; omitting it disables UDX idempotency for that request.

#### Request body

- Content type: `application/json`
- Schema: `TransferRequest`
- Required: yes
- Fields:
  - `from_account_id` (required) — The account to debit.
  - `to_account_id` (required) — The account to credit.
  - `amount` (required) — Amount to transfer, in dollars.

#### Responses

- `200` — The completed transfer. When an idempotency key was supplied, resending the identical request with the same key replays this response, marked with UDX-Idempotent-Replayed — the funds move only once. Without a key, UDX provides no transport replay guarantee.
- `400` — The request doesn't conform to this spec.
- `401` — No valid credential was provided.
- `403` — The API key lacks the `transfer` scope or is restricted to one account.
- `409` — This key is still in use or its response cannot be replayed. The mutation may have run; check `detail` before retrying.
- `422` — This key belongs to a different request.
- `429` — The Member's request rate is exhausted. Wait for `Retry-After`.
- `500` — Something went wrong on UDX's side.
- `503` — The transfer could not be resolved to a definite outcome: request admission or account setup is unavailable, or the transfer's result is unknown. If the request included an idempotency key, check your balances, then retry the identical request with the same key — the funds move at most once. A new key is a new transfer: never mint one to retry an attempt whose outcome is unknown. If no key was supplied, do not retry blindly; reconcile the balances before starting another transfer.
