Spring Lander docs

Overview

Spring Lander is a high-performance Solana transaction landing service. Construct your transaction as normal, add one tip instruction, sign, and send it to a Spring Lander endpoint — we deliver it directly to the leader over staked connections backed by 27+ million stake. Pay per transaction. If it doesn't land, you pay nothing.

How it works

Transactions are forwarded over staked QUIC connections directly to the current and upcoming leaders' TPU ports. There is no public RPC queue in the path and no middleman proxy — your signed bytes go from our edge to the leader.

Those edges run in 20 regions placed near validator concentrations, so the hop from your servers to ours is short and the hop from us to the leader is shorter. Pin the region closest to you for the lowest end-to-end latency.

Failed sends are free. Your tip is a transfer instruction inside your own transaction — it only executes if the transaction lands. No landing, no cost.

Tips

To use Spring Lander, add a standard SOL transfer instruction to one of the tip accounts below. Minimum tip: 0.001 SOL. Transactions are processed in order received and by tip amount — higher tips get priority during congestion.

SpWrza9E63MQuHeGnnfzmtLVCs3pBdjyKPXUABPo9nq
SpagSJmnh8E9cGT5Y431xPPaS2c1xLREGGCWN9yDeUf

Pick either account — randomize your choice to avoid write-lock contention when sending at high frequency.

Endpoints

RegionCodeEndpoint
North America — US
New Yorknycnyc.springlander.xyz
Ashburnashash.springlander.xyz
Chicagochichi.springlander.xyz
Atlantaatlatl.springlander.xyz
Miamimiamia.springlander.xyz
Dallasdaldal.springlander.xyz
Houstonhouhou.springlander.xyz
Kansas Citymcimci.springlander.xyz
Denverdenden.springlander.xyz
Salt Lake Cityslcslc.springlander.xyz
Phoenixphxphx.springlander.xyz
Los Angeleslaxlax.springlander.xyz
Seattleseasea.springlander.xyz
North America — Canada
Torontoyyzyyz.springlander.xyz
Vancouveryvryvr.springlander.xyz
Europe
Frankfurtfrafra.springlander.xyz
Amsterdamamsams.springlander.xyz
Londonlonlon.springlander.xyz
Asia-Pacific
Singaporesgpsgp.springlander.xyz
Tokyotyotyo.springlander.xyz

Global (geolocated): send.springlander.xyz — resolves to the nearest region. Region-specific endpoints are always faster; pin one if you can.

Paths on every region:

POST /send            JSON-RPC sendTransaction (drop-in RPC compatible)
POST /send-bin        raw serialized transaction (application/octet-stream)
POST /send-cors       /send with CORS headers, for browser integrations
POST /send-bin-cors   /send-bin with CORS headers
GET  /ping            keep-alive

Authentication

Every request needs an API key, passed as a query parameter:

https://fra.springlander.xyz/send?api-key=<your-api-key>

Get your key on Telegram.

Browser & CORS

Sending directly from the user's browser skips a round trip through your backend — the signed transaction goes straight from the wallet to Spring Lander. The -cors endpoint variants exist for exactly this:

POST /send-cors        JSON-RPC sendTransaction with CORS headers
POST /send-bin-cors    raw binary submission with CORS headers

Both return Access-Control-Allow-Origin: * and answer OPTIONS preflight requests. The plain /send and /send-bin endpoints do not send CORS headers and will be blocked by browsers.

  • Pages served over HTTPS must call the https:// endpoints — browsers hard-block mixed content, so plain http:// is unusable from a secure page.
  • Preflight: a JSON POST triggers an OPTIONS preflight on the first request; the connection is then reused, so subsequent sends skip it. Keep the connection warm with /ping.
  • /send-bin-cors with Content-Type: application/octet-stream also works from browsers and skips JSON encoding.
  • Use a browser-scoped API key: keys in front-end code are visible to users, so issue a separate key for browser traffic (domain-restricted keys available — ask on Telegram).

Full example URL:

https://fra.springlander.xyz/send-cors?api-key=<your-browser-key>

A complete browser code example is in the Examples section below.

Binary submission

POST the raw serialized transaction bytes to /send-bin with Content-Type: application/octet-stream. Skips JSON parsing on both ends — the fastest submission path over HTTP. Returns HTTP 200 with the transaction signature as plain text, or HTTP 400 with an error message.

curl -X POST "https://fra.springlander.xyz/send-bin?api-key=YOUR_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @signed-tx.bin

Keep-alive

GET /ping returns 200 pong. Ping every 30–45 seconds on the same TCP connection you send on — a reconnect adds a handshake to your next send. Most HTTP clients (reqwest, axios with a keep-alive agent, browser fetch to the same origin) reuse connections automatically.

// Node: force a keep-alive agent and ping on an interval
import { Agent } from "https";
const agent = new Agent({ keepAlive: true });
const BASE = "https://fra.springlander.xyz";

setInterval(() => {
  fetch(`${BASE}/ping`, { agent } as any).catch(() => {});
}, 35_000);
// send transactions with the same agent so the warm connection is reused

HTTP vs HTTPS

Both schemes work on every regional endpoint. On a warm keep-alive connection, throughput is identical; plain HTTP saves one round trip on cold connects only. Browser integrations must use HTTPS. Over plain HTTP your API key travels in cleartext — use a dedicated key for HTTP traffic.

Examples

import {
  Connection, Keypair, PublicKey, SystemProgram,
  TransactionMessage, VersionedTransaction,
} from "@solana/web3.js";

const ENDPOINT = "https://fra.springlander.xyz/send?api-key=YOUR_KEY";
const TIP_ACCOUNTS = [
  "SpWrza9E63MQuHeGnnfzmtLVCs3pBdjyKPXUABPo9nq",
  "SpagSJmnh8E9cGT5Y431xPPaS2c1xLREGGCWN9yDeUf",
];
const MIN_TIP_LAMPORTS = 1_000_000; // 0.001 SOL

async function sendWithSpring(payer: Keypair, instructions: any[], rpc: Connection) {
  // Spring Lander tip — required, minimum 0.001 SOL
  const tip = SystemProgram.transfer({
    fromPubkey: payer.publicKey,
    toPubkey: new PublicKey(TIP_ACCOUNTS[Math.floor(Math.random() * TIP_ACCOUNTS.length)]),
    lamports: MIN_TIP_LAMPORTS,
  });

  const { blockhash } = await rpc.getLatestBlockhash();
  const msg = new TransactionMessage({
    payerKey: payer.publicKey,
    recentBlockhash: blockhash,
    instructions: [...instructions, tip],
  }).compileToV0Message();

  const tx = new VersionedTransaction(msg);
  tx.sign([payer]);

  const res = await fetch(ENDPOINT, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0", id: 1, method: "sendTransaction",
      params: [Buffer.from(tx.serialize()).toString("base64"), { encoding: "base64" }],
    }),
  });
  const { result: signature } = await res.json();
  return signature;
}

FAQ