Transfers
Use a transfer when you already know the source, destination, blockchain, asset, and amount. Estimate the network fee if required, not a mandatory step, then create the transfer and use the returned Transaction.status as the lifecycle source of truth.
Estimate a transfer fee
POST /api/external/transactions/estimate_fee/
REST request body
{
"source": { "type": "VAULT", "id": "vault_123" },
"destination": { "type": "CONTACT", "id": "contact_456" },
"amount": "0.50",
"asset": "ETH",
"blockChain": "ETHEREUM",
"category": "TRANSFER"
}The SDK accepts chain and serializes it as blockChain. It injects category: "TRANSFER".
Response
interface FeeData {
expectedFeeInAsset: string;
asset: string;
expectedFeeInUSD: string;
baseFee?: string;
priorityFee?: string;
}
interface EstimatedFeeResponse {
high: FeeData;
medium: FeeData;
low: FeeData;
}JSON example
{
"high": {
"expectedFeeInAsset": "0.0018",
"asset": "ETH",
"expectedFeeInUSD": "5.40",
"baseFee": "0.0012",
"priorityFee": "0.0006"
},
"medium": {
"expectedFeeInAsset": "0.0014",
"asset": "ETH",
"expectedFeeInUSD": "4.20",
"baseFee": "0.0011",
"priorityFee": "0.0003"
},
"low": {
"expectedFeeInAsset": "0.0011",
"asset": "ETH",
"expectedFeeInUSD": "3.30",
"baseFee": "0.0010",
"priorityFee": "0.0001"
}
}JavaScript SDK
interface EstimateFeeRequest {
source: TransferPartyData;
destination: TransferPartyData;
amount: string;
asset: string;
chain: string;
}
estimateFee(request: EstimateFeeRequest): Promise<EstimatedFeeResponse>Create a transfer
POST /api/external/transactions/
REST request body
{
"source": { "type": "VAULT", "id": "vault_123" },
"destination": { "type": "CONTACT", "id": "contact_456" },
"amount": "0.50",
"asset": "ETH",
"blockChain": "ETHEREUM",
"category": "TRANSFER",
"externalId": "invoice-1001",
"memo": "Vendor payout #1001",
"feePayer": { "id": "vault_234" }
}SDK field | REST field | Type | Required | Description |
|---|---|---|---|---|
source | source | TransferPartyData | Yes | Sending party. |
destination | destination | TransferPartyData | Yes | Receiving party. |
amount | amount | string | Yes | Decimal transfer amount. |
asset | asset | string | Yes | Asset symbol. |
chain | blockChain | string | Yes | Blockchain identifier. |
externalId | externalId | string | No | Client reference. |
memo | memo | string | No | Human-readable note. |
feePayer.id | feePayer.id | string | No | Vault that pays the network fee when the chain supports sponsored fee payment. |
Response
{
"id": "transaction_123",
"orgId": "org_456",
"vaultId": "vault_123",
"status": "PENDING",
"transactionType": "OUTGOING",
"category": "TRANSFER",
"subCategory": "EXTERNAL_TRANSFER",
"createdAt": "2026-08-04T10:40:00Z",
"updatedAt": "2026-08-04T10:40:00Z",
"isDeleted": false,
"externalId": "invoice-1001",
"memo": "Vendor payout #1001",
"source": {
"type": "VAULT",
"id": "vault_123",
"subOrgId": "sub_org_123",
"name": "Treasury Vault"
},
"destination": {
"type": "CONTACT",
"id": "contact_456",
"name": "Operations Wallet",
"address": "0xAbC1234567890abcdef1234567890abcdef1234",
"chain": "ETHEREUM"
},
"blockChain": "ETHEREUM",
"asset": "ETH",
"amount": "0.50"
}JavaScript SDK
interface CreateTransferTransactionRequest {
source: TransferPartyData;
destination: TransferPartyData;
amount: string;
asset: string;
chain: string;
externalId?: string;
memo?: string;
feePayer?: { id: string };
}
createTransferTransaction(
request: CreateTransferTransactionRequest,
): Promise<Transaction>The SDK serializes only the fields above and injects category: "TRANSFER".