Skip to main content

Submit Transaction

Submit a signed transaction to the Aptos blockchain for execution.

When to Use This Method​

POST /transactions is essential for:

  • Token Transfers - Send APT or other tokens between accounts
  • Smart Contract Calls - Execute Move module functions
  • Module Deployment - Deploy new Move modules
  • Resource Management - Create, modify, or delete on-chain resources

Request Format​

Headers​

  • Content-Type: application/json
  • Accept: application/json

Body Structure​

{
"sender": "0x1",
"sequence_number": "0",
"max_gas_amount": "100000",
"gas_unit_price": "100",
"expiration_timestamp_secs": "1234567890",
"payload": {
"type": "entry_function_payload",
"function": "0x1::aptos_account::transfer",
"type_arguments": [],
"arguments": ["0x2", "100000"]
},
"signature": {
"type": "ed25519_signature",
"public_key": "0x...",
"signature": "0x..."
}
}

Implementation Examples​

import { 
Aptos,
AptosConfig,
Network,
Account,
Ed25519PrivateKey
} from "@aptos-labs/ts-sdk";

const config = new AptosConfig({
network: Network.MAINNET,
fullnode: "https://api-aptos-mainnet.n.dwellir.com/v1/YOUR_API_KEY",
});

const aptos = new Aptos(config);

// Simple APT transfer
async function transferAPT(
sender: Account,
recipient: string,
amount: number
) {
// Build transaction
const transaction = await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: {
function: "0x1::aptos_account::transfer",
functionArguments: [recipient, amount],
},
});

// Sign and submit
const pendingTxn = await aptos.signAndSubmitTransaction({
signer: sender,
transaction,
});

// Wait for confirmation
const committedTxn = await aptos.waitForTransaction({
transactionHash: pendingTxn.hash,
});

return committedTxn;
}

// Call smart contract function
async function callContractFunction(
sender: Account,
contractAddress: string,
moduleName: string,
functionName: string,
typeArgs: string[],
args: any[]
) {
const transaction = await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: {
function: `${contractAddress}::${moduleName}::${functionName}`,
typeArguments: typeArgs,
functionArguments: args,
},
});

const pendingTxn = await aptos.signAndSubmitTransaction({
signer: sender,
transaction,
});

return aptos.waitForTransaction({
transactionHash: pendingTxn.hash,
});
}

// Batch transaction submission
async function submitBatchTransactions(
sender: Account,
transactions: any[]
) {
const results = [];

for (const txData of transactions) {
const transaction = await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: txData,
});

const pendingTxn = await aptos.signAndSubmitTransaction({
signer: sender,
transaction,
});

results.push(pendingTxn);
}

// Wait for all transactions
const committed = await Promise.all(
results.map(txn =>
aptos.waitForTransaction({ transactionHash: txn.hash })
)
);

return committed;
}

Transaction Types​

1. Entry Function Payload​

Most common transaction type for calling Move functions:

const payload = {
type: "entry_function_payload",
function: "0x1::coin::transfer",
type_arguments: ["0x1::aptos_coin::AptosCoin"],
arguments: [recipientAddress, amount]
};

2. Script Payload​

For executing Move scripts:

const payload = {
type: "script_payload",
code: {
bytecode: "0xa11ceb0b...",
abi: {
name: "transfer_script",
visibility: "public",
generic_type_params: [],
params: ["address", "u64"]
}
},
type_arguments: [],
arguments: [recipient, amount]
};

3. Module Bundle Payload​

For deploying Move modules:

const payload = {
type: "module_bundle_payload",
modules: [
{
bytecode: "0xa11ceb0b...",
abi: { /* module ABI */ }
}
]
};

Gas Management​

Estimate Gas Before Submission​

async function estimateGas(
sender: Account,
payload: any
) {
// Simulate transaction to get gas estimate
const [simulation] = await aptos.transaction.simulate.simple({
signerPublicKey: sender.publicKey,
transaction: {
sender: sender.accountAddress,
data: payload,
},
});

return {
gasUsed: simulation.gas_used,
gasUnitPrice: simulation.gas_unit_price,
maxGasAmount: simulation.max_gas_amount,
totalCost: BigInt(simulation.gas_used) * BigInt(simulation.gas_unit_price)
};
}

// Use estimation before submission
async function submitWithGasEstimation(
sender: Account,
payload: any
) {
const gasEstimate = await estimateGas(sender, payload);

const transaction = await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: payload,
options: {
maxGasAmount: gasEstimate.maxGasAmount,
gasUnitPrice: gasEstimate.gasUnitPrice,
},
});

return aptos.signAndSubmitTransaction({
signer: sender,
transaction,
});
}

Multi-Signature Transactions​

Multi-Agent Transaction​

async function multiAgentTransaction(
primarySigner: Account,
secondarySigners: Account[],
payload: any
) {
// Build multi-agent transaction
const transaction = await aptos.transaction.build.multiAgent({
sender: primarySigner.accountAddress,
secondarySignerAddresses: secondarySigners.map(s => s.accountAddress),
data: payload,
});

// Primary signer signs
const primaryAuth = aptos.transaction.sign({
signer: primarySigner,
transaction,
});

// Secondary signers sign
const secondaryAuths = secondarySigners.map(signer =>
aptos.transaction.sign({ signer, transaction })
);

// Submit with all signatures
return aptos.transaction.submit.multiAgent({
transaction,
senderAuthenticator: primaryAuth,
additionalSignersAuthenticators: secondaryAuths,
});
}

Fee Payer Transaction​

async function sponsoredTransaction(
sender: Account,
sponsor: Account,
payload: any
) {
// Build transaction with fee payer
const transaction = await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: payload,
withFeePayer: true,
});

// Set fee payer address
transaction.feePayerAddress = sponsor.accountAddress;

// Sender signs
const senderAuth = aptos.transaction.sign({
signer: sender,
transaction,
});

// Sponsor signs as fee payer
const sponsorAuth = aptos.transaction.signAsFeePayer({
signer: sponsor,
transaction,
});

// Submit transaction
return aptos.transaction.submit.simple({
transaction,
senderAuthenticator: senderAuth,
feePayerAuthenticator: sponsorAuth,
});
}

Transaction Monitoring​

Wait for Transaction with Timeout​

async function waitForTransactionWithTimeout(
txnHash: string,
timeoutMs: number = 30000
) {
const startTime = Date.now();

while (Date.now() - startTime < timeoutMs) {
try {
const txn = await aptos.getTransactionByHash({
transactionHash: txnHash
});

if (txn.success) {
return { success: true, transaction: txn };
} else {
return { success: false, error: txn.vm_status };
}
} catch (error) {
if (error.status === 404) {
// Transaction not yet processed
await new Promise(resolve => setTimeout(resolve, 1000));
continue;
}
throw error;
}
}

throw new Error(`Transaction ${txnHash} timed out after ${timeoutMs}ms`);
}

Error Handling​

Common Transaction Errors​

async function submitTransactionSafely(
sender: Account,
payload: any
) {
try {
const pendingTxn = await aptos.signAndSubmitTransaction({
signer: sender,
transaction: await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: payload,
}),
});

const result = await aptos.waitForTransaction({
transactionHash: pendingTxn.hash,
});

if (!result.success) {
throw new Error(`Transaction failed: ${result.vm_status}`);
}

return result;
} catch (error) {
if (error.message.includes("SEQUENCE_NUMBER_TOO_OLD")) {
// Retry with fresh sequence number
const account = await aptos.getAccountInfo({
accountAddress: sender.accountAddress
});
// Retry transaction with new sequence number
} else if (error.message.includes("INSUFFICIENT_BALANCE")) {
throw new Error("Insufficient balance for transaction");
} else if (error.message.includes("TRANSACTION_EXPIRED")) {
throw new Error("Transaction expired - try again");
}

throw error;
}
}

Performance Optimization​

Parallel Transaction Submission​

class TransactionManager {
private sequenceNumber: bigint | null = null;

async submitParallelTransactions(
sender: Account,
payloads: any[]
) {
// Get starting sequence number
if (!this.sequenceNumber) {
const account = await aptos.getAccountInfo({
accountAddress: sender.accountAddress,
});
this.sequenceNumber = BigInt(account.sequence_number);
}

// Build all transactions with sequential sequence numbers
const transactions = await Promise.all(
payloads.map(async (payload, index) => {
const transaction = await aptos.transaction.build.simple({
sender: sender.accountAddress,
data: payload,
options: {
accountSequenceNumber: this.sequenceNumber! + BigInt(index),
},
});

return aptos.transaction.sign({ signer: sender, transaction });
})
);

// Submit all transactions in parallel
const submissions = await Promise.all(
transactions.map(signedTxn =>
aptos.transaction.submit.simple({
transaction: signedTxn.transaction,
senderAuthenticator: signedTxn,
})
)
);

// Update sequence number for next batch
this.sequenceNumber! += BigInt(payloads.length);

return submissions;
}
}

Need help? Contact our support team or check the Aptos documentation.