> This page is for NT Prop.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://partner.ninjatrader.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://partner.ninjatrader.com/_mcp/server.

# Submit Internal Transfer

POST https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer
Content-Type: application/json

### Transfer funds between a master account and a linked subaccount.**Available to:** Traders (the master account owner); organization administrators (any account in their organization)**Environments:** Live**[Rate Limit](/prop/overview/core-concepts/rate-limits):** 600 requests per hour, 30-second back-off, counts all requestsMove funds between a master account and one of its linked subaccounts. Set `fromAccountId` to the source account and `toAccountId` to the destination, then specify the `fundAmount` and `fundCurrencyId`. The response returns an `internalTransferId` and a transaction leg for each side of the transfer.The two accounts must be a linked master account and subaccount, and you must own the master account or be an administrator of its organization.**Field Details**You can look up account IDs using the Query Builder in the Admin Dashboard or the `/account/list` endpoint.The `fundAmount` must be greater than zero. The `fundCurrencyId` must correspond to either USD or EUR. Currency IDs are environment-specific, so use the `/currency/list` endpoint to retrieve valid IDs.The `reason` field is optional and records a note describing the transfer.The optional `idempotencyKey` is accepted on the request and is intended to support safely retrying a transfer. It is not yet used to deduplicate retries, so resubmitting a transfer can move funds more than once.**Response**The response returns two transaction legs, `fromFundTransaction` and `toFundTransaction`, one for each side of the transfer, and an `internalTransferId` that identifies the transfer. Each leg describes the fund transaction on its account: payment type, amount, currency, status, and timestamp.If the transfer is rejected, the response includes an `errorCode` and `errorText` describing the problem.**Response Codes**The `FundTransactionErrorCode` enum defines two outcome codes for an internal transfer that is accepted but does not complete:| Code                   | Meaning                                                   |
| ---------------------- | --------------------------------------------------------- |
| `IatFailedNoCashMoved` | The transfer failed and no funds were moved.              |
| `IatPending`           | The transfer is incomplete and needs manual intervention. |These codes are not yet returned by the endpoint. Today, a transfer that is accepted but does not complete returns `Unknown` in `errorCode`, with an `errorText` of "Internal transfer is pending; do not resubmit" (incomplete) or "Internal transfer could not be completed" (failed). In either case, do not resubmit the transfer.**Error Messages**A rejected transfer returns `HTTP 200` with an `errorText` message, not an error HTTP status. Check `errorText` to determine whether the request succeeded or failed.| Message                                                                          | Response             | Trigger                                                                                                          |
| -------------------------------------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `"Access is denied"`                                                             | 401                  | The API key lacks the required `Funds` access                                                                    |
| `"This endpoint is not enabled"`                                                 | 501                  | Internal transfers are not enabled for your organization (the feature is gated and off by default)               |
| `"Account not found"`                                                            | 200 (in `errorText`) | The accounts are not a linked master and subaccount, or the caller does not own or administer the master account |
| `"Source account <name> is <state>"` / `"Destination account <name> is <state>"` | 200 (in `errorText`) | The source or destination account is archived, closed, or restricted                                             |
| `"Source and destination accounts must differ"`                                  | 200 (in `errorText`) | `fromAccountId` and `toAccountId` are the same account                                                           |
| `"Only USD and EUR can be transferred between accounts"`                         | 200 (in `errorText`) | `fundCurrencyId` is a currency other than USD or EUR                                                             |
| `"Transfer amount must be greater than zero"`                                    | 200 (in `errorText`) | `fundAmount` is not greater than zero                                                                            |
| `"Not enough funds available to transfer"`                                       | 200 (in `errorText`) | The source account's transferable balance is less than `fundAmount`                                              |

Reference: https://partner.ninjatrader.com/prop/api/rest-api-endpoints/funds/submit-internal-transfer

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Body (application/json)

This endpoint expects a SubmitInternalTransfer.

- `fromAccountId` (long, required)
- `toAccountId` (long, required)
- `fundAmount` (double, required)
- `fundCurrencyId` (long, required)
- `reason` (string, optional)
- `idempotencyKey` (string, optional)

## Response

### 200

InternalTransferResponse

- `errorText` (string, optional) — Non-empty if the request failed
- `errorHeader` (string, optional) — Non-empty if the request failed
- `fromFundTransaction` (InternalTransferLeg, optional)
- `toFundTransaction` (InternalTransferLeg, optional)
- `internalTransferId` (string, optional)
- `errorCode` (enum, optional) — AccountLockFailed, AchDepositAboveMaximum, AchDepositAmountExceeded, AchDepositBelowMinimum, AchDepositExpected, AchDepositFrequencyExceeded, AchDepositHoldPeriod, AchDisclosureNotAccepted, AchNoApprovedApplications, AchPendingDepositExists, AchWithdrawalFrequencyExceeded, ApprovalStatusLocked, BankAccountNSF, ConcurrentRequestRejected, DuplicateAchReturn, DuplicateShadowTransaction, FullBalanceRequestPending, FullBalanceWithAchHolds, FullBalanceWithOpenPositions, FullBalanceWithPendingAch, IatFailedNoCashMoved, IatPending, InsufficientFunds, TransactionAlreadyApproved, TransactionAlreadyDeclined, TransactionNotApplicable, TransactionNotFound, Unknown, WireDepositHoldPeriod
  - Allowed values: `AccountLockFailed`, `AchDepositAboveMaximum`, `AchDepositAmountExceeded`, `AchDepositBelowMinimum`, `AchDepositExpected`, `AchDepositFrequencyExceeded`, `AchDepositHoldPeriod`, `AchDisclosureNotAccepted`, `AchNoApprovedApplications`, `AchPendingDepositExists`, `AchWithdrawalFrequencyExceeded`, `ApprovalStatusLocked`, `BankAccountNSF`, `ConcurrentRequestRejected`, `DuplicateAchReturn`, `DuplicateShadowTransaction`, `FullBalanceRequestPending`, `FullBalanceWithAchHolds`, `FullBalanceWithOpenPositions`, `FullBalanceWithPendingAch`, `IatFailedNoCashMoved`, `IatPending`, `InsufficientFunds`, `TransactionAlreadyApproved`, `TransactionAlreadyDeclined`, `TransactionNotApplicable`, `TransactionNotFound`, `Unknown`, `WireDepositHoldPeriod`

## Types

### InternalTransferLeg

- `fundPaymentType` (enum, required) — ACHR, ACHS, BOOKR, BOOKS, CKF, CKR, CKS, DCR, DCS, FPR, FX, IATR, IATS, MDF, SHR, SHS, TF, TT, WTF, WTR, WTS, WTSA, XFR
  - Allowed values: `ACHR`, `ACHS`, `BOOKR`, `BOOKS`, `CKF`, `CKR`, `CKS`, `DCR`, `DCS`, `FPR`, `FX`, `IATR`, `IATS`, `MDF`, `SHR`, `SHS`, `TF`, `TT`, `WTF`, `WTR`, `WTS`, `WTSA`, `XFR`
- `outgoing` (boolean, required)
- `fundAmount` (double, required)
- `fundCurrencyId` (long, required)
- `timestamp` (datetime, required)
- `accountId` (long, required)
- `internalTransferId` (string, optional)
- `fundDescription` (string, optional)
- `status` (enum, optional) — Approved, Declined, InReview, InSecondaryReview, InTransit, Locked, Pending, ReplicaNTC, ReviewCompleted, Suspended
  - Allowed values: `Approved`, `Declined`, `InReview`, `InSecondaryReview`, `InTransit`, `Locked`, `Pending`, `ReplicaNTC`, `ReviewCompleted`, `Suspended`
- `id` (long, optional)

## Examples

**Request**

```json
{
  "fromAccountId": 1,
  "toAccountId": 1,
  "fundAmount": 1.1,
  "fundCurrencyId": 1
}
```

**Response**

```json
{
  "errorText": "string",
  "errorHeader": "string",
  "fromFundTransaction": {
    "fundPaymentType": "ACHR",
    "outgoing": true,
    "fundAmount": 1.1,
    "fundCurrencyId": 1,
    "timestamp": "2024-01-15T09:30:00Z",
    "accountId": 1,
    "internalTransferId": "string",
    "fundDescription": "string",
    "status": "Approved",
    "id": 1
  },
  "toFundTransaction": {
    "fundPaymentType": "ACHR",
    "outgoing": true,
    "fundAmount": 1.1,
    "fundCurrencyId": 1,
    "timestamp": "2024-01-15T09:30:00Z",
    "accountId": 1,
    "internalTransferId": "string",
    "fundDescription": "string",
    "status": "Approved",
    "id": 1
  },
  "internalTransferId": "string",
  "errorCode": "AccountLockFailed"
}
```

**SDK Code**

```python
import requests

url = "https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer"

payload = {
    "fromAccountId": 1,
    "toAccountId": 1,
    "fundAmount": 1.1,
    "fundCurrencyId": 1
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"fromAccountId":1,"toAccountId":1,"fundAmount":1.1,"fundCurrencyId":1}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer"

	payload := strings.NewReader("{\n  \"fromAccountId\": 1,\n  \"toAccountId\": 1,\n  \"fundAmount\": 1.1,\n  \"fundCurrencyId\": 1\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"fromAccountId\": 1,\n  \"toAccountId\": 1,\n  \"fundAmount\": 1.1,\n  \"fundCurrencyId\": 1\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"fromAccountId\": 1,\n  \"toAccountId\": 1,\n  \"fundAmount\": 1.1,\n  \"fundCurrencyId\": 1\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer', [
  'body' => '{
  "fromAccountId": 1,
  "toAccountId": 1,
  "fundAmount": 1.1,
  "fundCurrencyId": 1
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"fromAccountId\": 1,\n  \"toAccountId\": 1,\n  \"fundAmount\": 1.1,\n  \"fundCurrencyId\": 1\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "fromAccountId": 1,
  "toAccountId": 1,
  "fundAmount": 1.1,
  "fundCurrencyId": 1
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://live.tradovateapi.com/v1/fundTransaction/submitinternaltransfer")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```