Documentation

Solana TPU Sender HTTP JSON-RPC API

HTTP JSON-RPC sendTransaction with Bearer or X-Api-Key authentication, base64 signed transactions, examples and retry handling.

// updated 2026-10-23

This page covers the HTTP JSON-RPC interface of the TPU Sender. The separate QUIK transport is listed on Endpoints and requires its own authorization and client setup.

Request format

Use your issued endpoint, for example https://sfls.l2.p2p.org. Send a signed base64 transaction containing a sufficient tip.

HeaderValue
Content-Typeapplication/json
AuthorizationBearer YOUR_API_KEY (preferred)
X-Api-KeyYOUR_API_KEY (alternative)

If both key headers are present, Authorization: Bearer takes priority.

# SIGNED_TX_BASE64 must already contain a tip of at least 150,000 lamports.
curl "$SENDER_URL" \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $SENDER_API_KEY" \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"sendTransaction\",\"params\":[\"$SIGNED_TX_BASE64\",{\"encoding\":\"base64\",\"skipPreflight\":true}]}"

TypeScript / Node.js

// Build the transaction with its tip, sign it, then serialize to base64.
const endpoint = process.env.SENDER_URL;
const apiKey = process.env.SENDER_API_KEY;
const signedTx = process.env.SIGNED_TX_BASE64;
if (!endpoint || !apiKey || !signedTx) throw new Error('Missing sender configuration');

const response = await fetch(endpoint, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${apiKey}`,
  },
  body: JSON.stringify({
    jsonrpc: '2.0', id: 1, method: 'sendTransaction',
    params: [signedTx, { encoding: 'base64', skipPreflight: true }],
  }),
});
const body = await response.json();
if (!response.ok || body.error) {
  throw new Error(JSON.stringify({ status: response.status, error: body.error }));
}
const signature = body.result;
// Confirm signature with getSignatureStatuses on your normal Solana RPC.

Success returns {"jsonrpc":"2.0","result":"TRANSACTION_SIGNATURE","id":1}. Submission and on-chain confirmation are separate events.

Errors

JSON-RPC codeHTTP statusMeaning
-32700400Malformed JSON
-32600400 / 403Invalid request or authentication failure
-32601200Method unavailable
-32602200 / 400Invalid parameters, missing tip or insufficient tip
-32603500Internal error
-32000500Server error
-32005429Client rate exceeded

Check the JSON-RPC error even when HTTP returns 200. Tip errors include Missing tip: no transfer to tip accounts found or Insufficient tip: provided X lamports, required Y lamports.

Connections and retries

Reuse HTTP connections. The documented keep-alive timeout is 30 seconds.

  • 429: wait for Retry-After. X-RateLimit-Limit and X-RateLimit-Remaining describe the current quota.
  • 400: correct the request before resubmitting.
  • 500 or network failure: check signature status, then retry the same signed transaction with exponential backoff while its blockhash remains valid.
  • Signature returned: track confirmation. Avoid blindly rebuilding and signing another transaction after an ambiguous timeout.

Reads, simulation and confirmation should use your regular RPC. Private-profile read access is optional; ask Supanode if you need it.