Quickstart
Get an API key, fund it with SOL, and send your first transaction through swqos.com in about ten minutes. Complete programs in TypeScript, Python, Rust and Go, each one runnable as written.
1. Get a key#
Open the dashboard and enter your email. We send a six digit code that works once and expires in ten minutes. There is no password to choose and none to lose.
On first sign-in an account is provisioned and your API key is shown. It stays available in the dashboard, so you can come back for it, but treat it as a secret: anyone holding it can spend your balance.
SWQOS_API_KEY from the environment for exactly that reason.2. Fund it#
Balances are prepaid in native SOL. In the dashboard, pick an amount and either connect a browser wallet or send SOL yourself to the address shown, including the memo. The memo is how we match a deposit to your account, so a deposit without one has to be credited by hand.
The minimum deposit is 0.01 SOL. Credit appears once the transaction reaches finalized commitment, which usually takes under a minute. At 0.0002 SOL per accepted send, 0.1 SOL is about five hundred transactions.
3. Send a transaction#
Each program below builds a one lamport self-transfer, signs it, submits it to swqos.com, and prints the receipt. Set SWQOS_API_KEY and PAYER_SECRET_KEY, then run it.
1import {2 Connection, Keypair, SystemProgram,3 TransactionMessage, VersionedTransaction, PublicKey,4} from "@solana/web3.js";56const API_KEY = process.env.SWQOS_API_KEY!;7const payer = Keypair.fromSecretKey(8 Buffer.from(JSON.parse(process.env.PAYER_SECRET_KEY!)),9);1011// Any RPC will do. We only need a blockhash; we never send through it.12const rpc = new Connection("https://api.mainnet-beta.solana.com", "confirmed");13const { blockhash } = await rpc.getLatestBlockhash("confirmed");1415const message = new TransactionMessage({16 payerKey: payer.publicKey,17 recentBlockhash: blockhash,18 instructions: [19 SystemProgram.transfer({20 fromPubkey: payer.publicKey,21 toPubkey: new PublicKey("11111111111111111111111111111111"),22 lamports: 1,23 }),24 ],25}).compileToV0Message();2627const tx = new VersionedTransaction(message);28tx.sign([payer]);2930const res = await fetch("https://send.swqos.com/v1/transactions", {31 method: "POST",32 headers: {33 Authorization: `Bearer ${API_KEY}`,34 "Content-Type": "application/json",35 },36 body: JSON.stringify({37 transaction: Buffer.from(tx.serialize()).toString("base64"),38 }),39});4041if (!res.ok) {42 const { error } = await res.json();43 throw new Error(`${error.code}: ${error.message}`);44}4546const receipt = await res.json();47console.log(receipt.signature, receipt.charged_lamports);4849// The receipt means we forwarded it. Confirm landing separately.50const status = await rpc.getSignatureStatuses([receipt.signature]);51console.log(status.value[0]?.confirmationStatus ?? "not yet visible");
A successful submission returns HTTP 200 and a receipt naming the signature, whether it was a duplicate, what you were charged, and what is left on your balance.
4. Confirm it landed#
The receipt means we forwarded your bytes and the upstream acknowledged the stream. Whether the transaction makes it into a block is the network’s decision, and every sample above ends by checking that separately with getSignatureStatuses.
Do this asynchronously. Blocking your send path on a confirmation query gives back the latency you came here for.
Where to go next#
- Send over QUIC if you care about latency. Holding one connection open removes the handshake from every send.
- Errors for the full contract, including which failures cost you nothing.
- Billing for the exact charge boundary.
The HTTPS endpoint is https://send.swqos.com. Everything else is in the reference.