---
title: "Initiate internal transfer"
method: POST
path: "/transfers/internal"
tags: ["Transfers"]
---

# Initiate internal transfer

`POST /transfers/internal`

Move funds between two wallets

## Headers

- `Idempotency-Key` string, required
- `X-Instance-ID` string, nullable

## Request body

- object
  - `data` object, required
    - `attributes` object, required
      - `customerPartyId` string — Customer party to act for (pty_*). Omit to act as your own party. To act for another party, pass the ID of a party that has authorized you to act on its behalf.
      - `amount` integer, required — Amount in cents.
      - `sourceWalletId` string, required — Source wallet ID (wal_*).
      - `destWalletId` string, required — Destination wallet ID (wal_*).
      - `description` string — Transfer description. Maximum 80 characters.
      - `tags` object — Key-value metadata stored on the resource. At most 30 keys; keys 1-128 characters, alphanumeric and underscores; values 1-256 characters. Visible to anyone who can read the resource; do not include sensitive data.

## Response `200`

Successful Response

- object
  - `data` object, required
    - `type` 'transfer', required — Resource type. Always `transfer`.
    - `id` string, required — Transfer ID (trf_*).
    - `attributes` object, required
      - `type` 'deposit' | 'withdrawal' | 'internal', required — Transfer type.
      - `amount` integer, required — Amount in cents.
      - `currency` string, required — Currency code.
      - `fee` object, nullable, required — Fee added to your cost as the sender for an instant withdrawal. Null when no fee applies, the fee was voided, or your party is not the fee payer.
        - `amount` integer, required — Fee amount in cents.
        - `currency` 'USD', required — Currency of the fee.
        - `payer` 'sender', required — Party role charged the fee.
        - `applied` 'on_top', required — The fee is added to the sender's cost without reducing the principal amount.
      - `status` 'CREATED' | 'APPROVAL_DENIED' | 'PROCESSING' | 'IN_REVIEW' | 'COMPLETED' | 'FAILED' | 'RETURNED' | 'CANCELED', required — Transfer status.
      - `method` 'standard' | 'instant' | 'wire', nullable, required — Requested delivery method, when available.
      - `rail` 'ach' | 'wire' | 'internal' | 'realtime', nullable, required — Executed transfer rail, when available.
      - `description` string, nullable, required — Transfer description. Maximum 80 characters.
      - `tags` object, required — Metadata visible to anyone who can read the resource.
      - `externalAccountDisplayMask` string, nullable, required — Masked external account number.
      - `expectedAvailableAt` string, nullable, required — RFC 3339 timestamp when the funds are expected to be available, or null when unknown.
      - `failure` object, nullable, required — Failure details when this transfer failed.
        - `code` string, nullable, required — Failure code, when available.
        - `reason` string, nullable, required — Failure reason, when available.
      - `return` object, nullable, required — Return details when this transfer was returned.
        - `code` string, nullable, required — Return code, when available.
        - `reason` string, nullable, required — Return reason, when available.
        - `returnedAt` string, nullable, required — RFC 3339 timestamp when this transfer was returned, or null.
      - `submittedAt` string, nullable, required — RFC 3339 timestamp when this transfer was submitted, or null.
      - `settledAt` string, nullable, required — RFC 3339 timestamp when this transfer settled, or null.
      - `createdAt` string, required — RFC 3339 timestamp when this transfer was created.
      - `updatedAt` string, nullable, required — RFC 3339 timestamp when this transfer was last updated, or null.
    - `relationships` object, required
      - `party` object, required — Party that owns the transfer.
        - `data` object, required — Related resource identifier.
          - `type` 'party', required — Resource type. Always `party`.
          - `id` string, required
      - `wallet` object, required — Wallet for this transfer.
        - `data` object, required — Related resource identifier.
          - `type` 'wallet', required — Resource type. Always `wallet`.
          - `id` string, required
      - `destWallet` object — Destination wallet for internal transfers.
        - `data` object, nullable, required — Related resource identifier.
          - `type` 'wallet', required — Resource type. Always `wallet`.
          - `id` string, required
      - `externalAccount` object, required — External account used for this transfer, when available.
        - `data` object, nullable, required — Related resource identifier.
          - `type` 'externalAccount', required — Resource type. Always `externalAccount`.
          - `id` string, required
      - `transaction` object, required — Primary transaction for this transfer, when available.
        - `data` object, nullable, required — Related resource identifier.
          - `type` 'transaction', required — Resource type. Always `transaction`.
          - `id` string, required

## Other responses

- `400` — Validation Error
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found. Returned when the resource does not exist, or when it exists but is not accessible to your account. The two cases are intentionally indistinguishable, so that resource IDs cannot be enumerated by probing.
- `409` — Conflict
- `422` — Validation Error. The response contains one error object for each invalid request value.
- `428` — Precondition Required
- `429` — Too Many Requests
- `500` — Internal Server Error
- `501` — Not Implemented
- `502` — Bad Gateway
- `503` — Service Unavailable

## Changes

- **2026-09-23** `bcf3b028c3e5` — 1 warning, 2 info
  - removed the request property `data/attributes/partyId`
  - added the new optional request property `data/attributes/customerPartyId`
  - added the required property `data/attributes/fee` to the response with the `200` status
- **2026-09-22** `4a05af81217f` — 7 warning
  - added the new `ach` enum value to the `data/attributes/rail/anyOf[subschema #1]/` response property for the response status `200`
  - added the new `instant` enum value to the `data/attributes/method/anyOf[subschema #1]/` response property for the response status `200`
  - added the new `internal` enum value to the `data/attributes/rail/anyOf[subschema #1]/` response property for the response status `200`
  - added the new `realtime` enum value to the `data/attributes/rail/anyOf[subschema #1]/` response property for the response status `200`
  - …3 more
- **2026-09-02** `c7c12da5915f` — 12 info
  - added the optional property `errors/items/meta/limitScope` to the response with the `400` status
  - added the optional property `errors/items/meta/limitScope` to the response with the `401` status
  - added the optional property `errors/items/meta/limitScope` to the response with the `403` status
  - added the optional property `errors/items/meta/limitScope` to the response with the `404` status
  - …8 more
- **2026-08-27** `359d267dca88` — 1 info
  - deleted the `header` request parameter `X-Agent-ID` with deprecation
- …earlier changes not shown

[Full history](https://skmtc.dev/natural/apis/natural-api/changes/transfers/internal/post.md)

---

[API](https://skmtc.dev/natural/apis/natural-api.md) · [All operations](https://skmtc.dev/natural/apis/natural-api/llms.txt) · [OpenAPI document](https://skmtc.dev/natural/apis/natural-api/revisions/ca3882d75a00?raw)
