sendTransaction
Submits a signed transaction to the cluster for processing.
Common use cases
| Execute SPL Token Transfer | Broadcast signed token transfer transaction to move SPL tokens between accounts. After constructing transfer instruction with Token Program, signing with wallet, and obtaining recent blockhash, submit to network and monitor confirmation via getSignatureStatuses. |
| Deploy Program Upgrade | Submit buffer write and upgrade authority transactions to deploy new program version. Use skipPreflight: false to catch deployment errors before consuming upgrade authority. Monitor confirmation to finalized before switching traffic to upgraded program. |
| Submit High-Frequency Trading Orders | Broadcast time-sensitive DEX transactions for arbitrage or market making. Enable skipPreflight: true to minimize latency, set competitive priority fees via ComputeBudgetProgram, and implement client-side retry logic for expired blockhashes during network congestion. |
| Batch NFT Minting Operations | Send signed mint transactions for NFT collection launches. Coordinate multiple sequential sendTransaction calls with rate limiting, track pending signatures, and implement blockhash refresh logic when minting spans beyond 150 slots. |
| Execute Wallet Transaction from dApp | Submit user-approved transaction from browser wallet integration. Wallet serializes, signs, and calls sendTransaction while dApp polls confirmation status. Handle 'User rejected' vs network errors differently in UX flow. |
Parameters
transaction (string, required)
Fully-signed Transaction, as encoded string.
config (object, optional)
Configuration object containing the following fields:
Fields:
encoding(string): Encoding used for the transaction data. Values:base58(slow, DEPRECATED), orbase64.skipPreflight(bool): Whentrue, skip the preflight transaction checks. Default:false.preflightCommitment(string): Commitment level to use for preflight. See Configuring State Commitment. Defaultfinalized.maxRetries(usize): Maximum number of times for the RPC node to retry sending the transaction to the leader. If this parameter not provided, the RPC node will retry the transaction until it is finalized or until the blockhash expires.minContextSlot(number): Set the minimum slot at which to perform preflight transaction checks
Request
- cURL
- JavaScript
- Python
curl https://solana-mainnet.api.syndica.io/api-key/YOUR_API_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTBU6EhdB4RD8CP2xUxr2u3d6fos36PD98XS6oX8TQjLpsMwncs5DAMiD4nNnR8NBfyghGCWvCVifVwvA8B8TJxE1aiyiv2L429BCWfyzAme5sZW8rDb14NeCQHhZbtNqfXhcp2tAnaAT"
]
}'
// Using fetch
const response = await fetch('https://solana-mainnet.api.syndica.io/api-key/YOUR_API_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTBU6EhdB4RD8CP2xUxr2u3d6fos36PD98XS6oX8TQjLpsMwncs5DAMiD4nNnR8NBfyghGCWvCVifVwvA8B8TJxE1aiyiv2L429BCWfyzAme5sZW8rDb14NeCQHhZbtNqfXhcp2tAnaAT"
]
})
});
const data = await response.json();
console.log(data);
import requests
import json
url = 'https://solana-mainnet.api.syndica.io/api-key/YOUR_API_KEY'
headers = {'Content-Type': 'application/json'}
data = {
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
"4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b7yGrRQcWyaqsaBCncVG7BFggS8w9snUts67BSh3EqKpXLUm5UMHfD7ZBe9GhARjbNQMLJ1QD3Spr6oMTBU6EhdB4RD8CP2xUxr2u3d6fos36PD98XS6oX8TQjLpsMwncs5DAMiD4nNnR8NBfyghGCWvCVifVwvA8B8TJxE1aiyiv2L429BCWfyzAme5sZW8rDb14NeCQHhZbtNqfXhcp2tAnaAT"
]
}
response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json())
Replace mainnet with devnet in the URL to query devnet instead.
Response
{
"jsonrpc": "2.0",
"result": "2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb",
"id": 1
}
Response Fields
Return value: string
First Transaction Signature embedded in the transaction, as base-58 encoded string (transaction id)
FAQ and Troubleshooting
Why did my transaction fail with 'Blockhash not found'?
Transactions include a recent blockhash that expires after ~150 slots (~60-90 seconds). If submission is delayed or retried after expiration, the cluster rejects it with 'Blockhash not found'. Solution: Fetch fresh blockhash with getLatestBlockhash and reconstruct the transaction. Track lastValidBlockHeight to detect expiration before submission.
Should I enable or disable skipPreflight?
Enable skipPreflight: true when submission speed is critical (e.g., arbitrage, MEV) and you've already validated the transaction client-side. Disable (default: false) for user-facing applications where safety matters more than speed. Preflight catches signature failures, insufficient balance, program errors, and blockhash issues before wasting fees.
Does sendTransaction wait for confirmation?
No. The method returns immediately after the RPC node receives the transaction, providing only the signature. It does NOT wait for cluster processing, inclusion in a block, or any confirmation level. Use signatureSubscribe (WebSocket) or poll getSignatureStatuses (HTTP) to track confirmation status after sending.
What does maxRetries control?
maxRetries configures how many times the RPC node will resubmit the transaction to the cluster's TPU if it doesn't get rooted. This is server-side retry logic, separate from client-side retries. Default varies by node implementation. Higher values increase landing chance but may cause duplicate submission if transaction succeeds on earlier attempt.
Why does sendTransaction return a signature but the transaction never lands?
Success response only means the RPC node accepted the transaction for forwarding, not that it reached validators or got included on-chain. Common causes: 1) Network congestion dropped the transaction, 2) Invalid transaction rejected during validation, 3) Blockhash expired before inclusion, 4) Insufficient priority fees for congested blocks. Always confirm with getSignatureStatuses.
Related Methods
getLatestBlockhash
Retrieves recent blockhash and lastValidBlockHeight required for transaction construction. Call immediately before building transaction to ensure blockhash validity. Compare lastValidBlockHeight with current slot after sendTransaction to detect expired transactions.
getSignatureStatuses
Polls transaction confirmation status after sendTransaction. Returns confirmation level (processed/confirmed/finalized), error details, and slot information. Essential for detecting on-chain success or failure since sendTransaction only returns signature without confirmation.
simulateTransaction
Simulates transaction execution without submitting to network. Use before sendTransaction to preview compute units consumed, verify program logic, and catch errors. Alternative to preflight checks when you need detailed simulation results.
signatureSubscribe
WebSocket subscription for real-time transaction confirmation notifications. More efficient than polling getSignatureStatuses for applications monitoring many transactions. Subscribe immediately after sendTransaction to track status changes.
getRecentPrioritizationFees
Returns recent priority fees paid by transactions. Use before sendTransaction to set competitive priority fees via ComputeBudgetProgram instructions. Higher fees increase transaction landing probability during network congestion.