Carbium for Trading Bots
Build Solana trading bots on Carbium with the right split between RPC, Swap API, CQ1-backed quote flows, gRPC streaming, and production-safe key handling.
Carbium for Trading Bots
Trading bots usually fail for boring reasons before they fail for strategy reasons. The common breakpoints are stale reads, bursty retries, exposed keys, and execution paths that mix quote, sign, and submit concerns in one fragile process.
Carbium's public docs already cover the main surfaces a Solana bot needs:
- RPC for reads, writes, and transaction submission over
https://rpc.carbium.io/?apiKey=... - Swap API for quote and executable transaction flows over
https://api.carbium.io/api/v2/quote - CQ1-backed routing when your strategy needs the Swap API's routing engine instead of a single DEX path
- gRPC at
grpc.carbium.iofor transaction-centric real-time feeds when polling is too slow or too expensive
Part of the Carbium Solana infrastructure stack.
Use the right Carbium surface for each bot job
| Bot job | Best Carbium surface | Why |
|---|---|---|
| Read slots, balances, recent blockhashes, and signature status | RPC | Standard Solana JSON-RPC with normal SDK support |
| Request an executable route for a swap | Swap API | The published quote flow can return a serialized transaction when user_account is included |
| Submit the signed transaction | RPC | Keeps execution on the standard Solana submission path |
| Watch transaction-heavy flows with less polling | gRPC | Better fit once bot traffic or latency pressure makes constant RPC reads wasteful |
| Compare and execute routed swaps across supported DEX liquidity | Swap API / CQ1 | Carbium documents CQ1 as the routing layer behind its API execution path |
This page owns the build pattern for bot teams. For detailed throttling behavior, use Solana RPC Rate Limits Explained. For key handling, use API Key Security Best Practices.
Recommended architecture for most bots
The cleanest production split is:
- A reader that pulls RPC state or listens on gRPC.
- A decision layer that decides whether the signal is actionable.
- An execution service that requests a quote, signs, submits, and confirms.
Keep the keys and signing boundary inside backend services you control. Do not let one loop both discover opportunities and blindly hammer submission retries without checking chain state.
flowchart LR
A["Market state"] --> B["Bot reader"]
B --> C["Decision layer"]
C --> D["Quote request<br/>api.carbium.io/api/v2/quote"]
D --> E["Signed transaction"]
E --> F["RPC submit<br/>rpc.carbium.io"]
F --> G["Status + confirmation"]
B --> H["gRPC listener<br/>grpc.carbium.io"]
H --> C
Start simple: quote on API, execute on RPC
If your strategy is route-aware and execution-focused, a minimal Carbium bot usually needs only two live paths:
- request a quote from the Swap API
- submit the resulting signed transaction through RPC
That keeps the first version of the bot operational without forcing a streaming stack on day one.
Minimal TypeScript flow
import { Connection, Keypair, VersionedTransaction } from "@solana/web3.js";
import bs58 from "bs58";
const RPC_URL = `https://rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`;
const QUOTE_URL = "https://api.carbium.io/api/v2/quote";
const connection = new Connection(RPC_URL, "confirmed");
const signer = Keypair.fromSecretKey(bs58.decode(process.env.BOT_PRIVATE_KEY!));
async function fetchExecutableQuote(params: {
srcMint: string;
dstMint: string;
amountIn: string;
}) {
const url = new URL(QUOTE_URL);
url.searchParams.set("src_mint", params.srcMint);
url.searchParams.set("dst_mint", params.dstMint);
url.searchParams.set("amount_in", params.amountIn);
url.searchParams.set("slippage_bps", "50");
url.searchParams.set("user_account", signer.publicKey.toBase58());
const res = await fetch(url, {
headers: {
"X-API-KEY": process.env.CARBIUM_API_KEY!,
"Accept": "application/json",
},
});
if (!res.ok) {
throw new Error(`Quote failed with ${res.status}`);
}
const quote = await res.json();
if (!quote.txn) {
throw new Error("Quote response did not include an executable transaction");
}
return quote;
}
async function executeQuotedSwap() {
const quote = await fetchExecutableQuote({
srcMint: "So11111111111111111111111111111111111111112",
dstMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
amountIn: "10000000",
});
const transaction = VersionedTransaction.deserialize(
Buffer.from(quote.txn, "base64")
);
transaction.sign([signer]);
const signature = await connection.sendTransaction(transaction, {
skipPreflight: false,
maxRetries: 3,
});
const status = await connection.confirmTransaction(signature, "confirmed");
return { signature, status, routePlan: quote.routePlan };
}This pattern matches Carbium's published docs:
user_accounton the quote request returns an executable transaction payload- the signed transaction is submitted through standard Solana RPC
- confirmation should be checked before the bot decides the trade failed
When to add gRPC
Do not add streaming because it sounds more advanced. Add it when your current bot shape proves that polling is the wrong tool.
Good reasons to add gRPC:
- you monitor many programs or transaction flows continuously
- your bot reacts to transaction-level events and polling misses timing windows
- repeated RPC reads are creating rate-limit pressure
- you need one backend listener to feed several strategy workers
Carbium's public docs position grpc.carbium.io as the real-time path and document that gRPC starts at the Business tier. Use that as a design checkpoint: if streaming is mandatory for the bot to work, validate the plan and endpoint before you scale the strategy.
Minimal listener shape
import WebSocket from "ws";
const ws = new WebSocket(
`wss://grpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`
);
ws.on("open", () => {
ws.send(
JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "transactionSubscribe",
params: [
{
vote: false,
failed: false,
accountInclude: ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"],
accountExclude: [],
accountRequired: [],
},
{
commitment: "confirmed",
encoding: "base64",
transactionDetails: "full",
showRewards: false,
maxSupportedTransactionVersion: 0,
},
],
})
);
});Use streaming to feed the decision layer. Keep execution and retry policy separate so one noisy feed does not turn into duplicate submissions.
Production notes that matter more than strategy tweaks
Separate secrets and workloads
Use separate environment variables for:
CARBIUM_RPC_KEYCARBIUM_API_KEY- signing material such as
BOT_PRIVATE_KEY
If you run multiple bots or environments, split keys per service where practical. That limits blast radius and makes rate anomalies easier to isolate.
Treat 429s as architecture feedback
If a bot gets 429 responses, do not just raise retry counts. The usual fixes are:
- reduce duplicated reads
- add jitter and backoff
- centralize request budgeting
- move hot monitoring paths to gRPC when that actually reduces polling pressure
The detailed throttling guidance belongs on the rate-limits page, not here.
Confirm before replaying
The most expensive bot bug is often duplicate execution. Before retrying sendTransaction, check signature status first and decide whether the original submission already landed.
Keep quote and submit logs correlated
Store enough information to answer:
- which signal triggered the trade
- which quote parameters were used
- which route plan came back
- which signature was submitted
- whether the final status was confirmed, failed, or abandoned
That makes post-trade debugging much faster than trying to reconstruct intent from RPC logs alone.
Bot launch checklist
Before you run real capital through the bot, verify:
- the bot can complete a quote -> sign -> submit -> confirm loop in your target environment
- RPC and API keys live only in backend env vars or a secret manager
sendTransactionretries always check signature status first- rate-limit handling uses backoff instead of parallel blind retries
- gRPC is only required if your strategy truly needs streaming
- the expected workload fits the Carbium plan you selected
This page is the implementation guide for bot architecture. Keep rate-limit rules, plan selection, and key-hardening details in their dedicated canonical pages rather than duplicating them inside strategy docs.
Building a Solana trading bot on Carbium? Start with a controlled backend flow and validate plan fit at carbium.io.
Updated about 7 hours ago
