Skip to main content

Internal Transfers Guide

This guide explains how to perform internal transfers between accounts at the same bank, covering the three available methods and their use cases.

Overview

Internal transfers move funds between accounts within the same bank, without going through the PIX network. They are processed instantly.

There are three ways to identify the destination account:

MethodEndpointDestination requirementUse case
By Account ID/transfers/internalMust have API access enabledTransfers between your own accounts
By Document/transfers/internal/by-documentAny account at the bankTransfers to any account holder
By Branch/Account/transfers/internal/by-bank-accountMust have API access enabledWhen you have branch and account number

1. Transfer by Account ID

The most performant method. Use when both source and destination accounts are registered in the API.

Endpoint: POST /v1/accounts/{accountId}/transfers/internal

curl -X POST "https://api.corpxapi.com/v1/accounts/{accountId}/transfers/internal" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-yourcompany" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: int-001" \
-d '{
"destinationAccountId": "773107de-139e-48d1-9462-f4e88f251891",
"value": 1500.00,
"description": "Transfer between branches",
"identifier": "branch-transfer-001"
}'

Fields:

FieldTypeRequiredDescription
destinationAccountIdstring (UUID)YesDestination account UUID (API internal ID)
valuenumberYesAmount in BRL (max 2 decimal places)
descriptionstringYesTransfer description
identifierstringNoUnique identifier for tracking

Response (200):

{
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"destinationAccountId": "773107de-139e-48d1-9462-f4e88f251891",
"value": 1500.00,
"status": "COMPLETED",
"description": "Transfer between branches",
"identifier": "branch-transfer-001",
"createdAt": "2026-03-18T15:30:00Z"
}

2. Transfer by Document (CPF/CNPJ)

Use when the destination account is not registered in the API. Works for any account in the banking ecosystem.

Endpoint: POST /v1/accounts/{accountId}/transfers/internal/by-document

curl -X POST "https://api.corpxapi.com/v1/accounts/{accountId}/transfers/internal/by-document" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-yourcompany" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: int-002" \
-d '{
"document": "12345678000190",
"value": 500.00,
"description": "Supplier payment",
"identifier": "supplier-payment-002"
}'

Fields:

FieldTypeRequiredDescription
documentstringYesCPF or CNPJ of the destination account holder (numbers only)
valuenumberYesAmount in BRL
descriptionstringYesTransfer description
identifierstringNoUnique identifier for tracking

3. Transfer by Branch and Account Number

Use when you have the branch and account number. Both accounts must be registered in the API.

Endpoint: POST /v1/accounts/{accountId}/transfers/internal/by-bank-account

curl -X POST "https://api.corpxapi.com/v1/accounts/{accountId}/transfers/internal/by-bank-account" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-yourcompany" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: int-003" \
-d '{
"branch": "0001",
"accountNumber": "200038274",
"value": 250.00,
"description": "Refund",
"identifier": "refund-003"
}'

Fields:

FieldTypeRequiredDescription
branchstringYesDestination account branch
accountNumberstringYesDestination account number
valuenumberYesAmount in BRL
descriptionstringYesTransfer description
identifierstringNoUnique identifier for tracking

Which method to choose?

Does the destination account have API access?
├── YES → Do you have the Account ID (UUID)?
│ ├── YES → Use /transfers/internal (fastest)
│ └── NO → Use /transfers/internal/by-bank-account
└── NO → Use /transfers/internal/by-document

Practical examples:

  • Moving funds between your company's branches/transfers/internal (by Account ID)
  • Paying a supplier at the bank/transfers/internal/by-document (by CPF/CNPJ)
  • Transferring to a known account by branch number/transfers/internal/by-bank-account

Webhooks

After an internal transfer, both parties receive a webhook:

  • Sender: transfer.internal.out
  • Receiver: transfer.internal.in
{
"id": "evt_abc123",
"type": "transfer.internal.in",
"eventType": "transfer.internal.in",
"accountId": "773107de-139e-48d1-9462-f4e88f251891",
"data": {
"amount": 1500.00,
"currency": "BRL",
"status": "SUCCESS",
"completedAt": "2026-03-18T15:30:00Z",
"source": {
"name": "SOURCE COMPANY LTDA",
"taxId": "12345678000100"
},
"destination": {
"name": "DESTINATION COMPANY LTDA",
"taxId": "12345678000200"
}
}
}

To receive these webhooks, include transfer.internal.in and/or transfer.internal.out in your subscription event types.

Common Errors

CodeMessageCause
400destinationAccountId is requiredMissing required field
400value must be positiveInvalid amount
404destination account not foundDestination not found (by-bank-account)
422insufficient_balanceInsufficient balance in source account
502unable to create internal transferBanking partner error