Only this pageAll pages
Powered by GitBook
1 of 21

Temporal Docs

Nozomi

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

CURL

Please specify base64 encoding, Solana recognizes base58 as default. If you do not specify, you might get malformed transaction error

curl https://nozomi.temporal.xyz/?c=<YOUR_API_KEY> \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "sendTransaction",
    "params": [
      "<YOUR_BASE_64_ENCODED_TXN_BYTES>",
      {
        "encoding": "base64"
      }
    ]
  }'

Tipping & FAQ

Transaction Tip

Each transaction must include a system transfer instruction to the Nozomi tip address, with a minimum tip of 0.001 SOL. Increasing the tip raises your transaction’s priority in the queue—higher tips settle faster.

These tips compensate the Jito tip and pay validators for staked connections. If Jito validates the transaction, the tip goes to the Jito validator. In that case, Nozomi forwards the entire tip to Jito.

Here is a breakdown of tips by percentile.

Nozomi Tip Addresses

Send your tip to any one of these 17 addresses. To optimize performance and avoid write CU exhaustion, use a random different address for each transaction.

Priority Fee

Nozomi gets your transaction to the scheduler. At this point, priority fees matter. It is recommended to set CU price to at least 1,000,000 lamports, or expect subpar performance.

Retries

Nozomi will retry transactions until confirmation or expiry. Nozomi will prioritize retries based on the amount tipped.

Rate Limits

Each API key has an associated rate limit.

QoS Priority

Clients with high failure rate will have a QoS penalty to their priority. For example if only 10% of your transactions successfully land, your priority will be discounted to 10%. This is based on last 30 minutes of transaction sending.

Optimized Routing

What makes Nozomi unique is how it routes transactions through the TPU. It knows exactly when and how to send transactions.

Nozomi does not simulate transactions.

Avoiding Front-Running

There is Front Running Protection URL that only sends through a custom whitelist of trusted validators (Helius, Coinbase, etc.) .

Set strict slippage tolerances and calculate minAmountOut to have protections against front-running.

Customizability

Only pay the tip if you execute your desired opportunity. Since the tip is a transfer, if you detect someone captured the opportunity you wanted, you can fail your transaction to avoid paying the tip.

If you are a high tipper, please reach out for custom rate limits.

Contact

Reach out via Telegram: @ h3ll0wrld

"TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq",
"noz3jAjPiHuBPqiSPkkugaJDkJscPuRhYnSpbi8UvC4",
"noz3str9KXfpKknefHji8L1mPgimezaiUyCHYMDv1GE",
"noz6uoYCDijhu1V7cutCpwxNiSovEwLdRHPwmgCGDNo",
"noz9EPNcT7WH6Sou3sr3GGjHQYVkN3DNirpbvDkv9YJ",
"nozc5yT15LazbLTFVZzoNZCwjh3yUtW86LoUyqsBu4L",
"nozFrhfnNGoyqwVuwPAW4aaGqempx4PU6g6D9CJMv7Z",
"nozievPk7HyK1Rqy1MPJwVQ7qQg2QoJGyP71oeDwbsu",
"noznbgwYnBLDHu8wcQVCEw6kDrXkPdKkydGJGNXGvL7",
"nozNVWs5N8mgzuD3qigrCG2UoKxZttxzZ85pvAQVrbP",
"nozpEGbwx4BcGp6pvEdAh1JoC2CQGZdU6HbNP1v2p6P",
"nozrhjhkCr3zXT3BiT4WCodYCUFeQvcdUkM7MqhKqge",
"nozrwQtWhEdrA6W8dkbt9gnUaMs52PdAv5byipnadq3",
"nozUacTVWub3cL4mJmGCYjKZTnE9RbdY5AP46iQgbPJ",
"nozWCyTPppJjRuw2fpzDhhWbW355fzosWSzrrMYB1Qk",
"nozWNju6dY353eMkMqURqwQEoM3SFgEKC6psLCSfUne",
"nozxNBgWohjR75vdspfxR5H9ceC7XXH99xpxhVGt3Bb"

TypeScript

Use full service RPC for fetching latest blockhash. Nozomi only supports sendTransaction.

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

const NOZOMI_ENDPOINT = "https://nozomi.temporal.xyz/?c=<YOUR_API_KEY>";
const NOZOMI_TIP = new PublicKey("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq");
const MIN_TIP_AMOUNT = 1_000_000;

const SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com";

async function sendNozomiTxn(ixns: TransactionInstruction[], signer: Keypair, nozomiRpcClient: Connection, solanaRpcClient: Connection): Promise<TransactionSignature> {
    const tipIxn = SystemProgram.transfer({
        fromPubkey: signer.publicKey,
        toPubkey: NOZOMI_TIP,
        lamports: MIN_TIP_AMOUNT
    });
    ixns.push(tipIxn);

    const { blockhash } = await solanaRpcClient.getLatestBlockhash();

    const messageV0 = new TransactionMessage({
        payerKey: signer.publicKey,
        recentBlockhash: blockhash,
        instructions: ixns,
    }).compileToV0Message();

    const versionedTxn = new VersionedTransaction(messageV0);

    versionedTxn.sign([signer]);

    return await nozomiRpcClient.sendTransaction(versionedTxn);
}

function buildIxns(): TransactionInstruction[] {
    // your instruction building logic here..
    return [];
}

async function main() {
    const nozomiRpcClient = new Connection(NOZOMI_ENDPOINT);

    const solanaRpcClient = new Connection(SOLANA_RPC_ENDPOINT);

    // replace with actual keypair loading logic
    const signer = Keypair.generate();

    const ixns = buildIxns();

    const signature = await sendNozomiTxn(ixns, signer, nozomiRpcClient, solanaRpcClient);

    console.log(`Transaction sent with signature: ${signature}`);
}

main().catch(err => {
    console.error(err);
});

JavaScript

Use full service RPC for fetching latest blockhash. Nozomi only supports sendTransaction.

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

const NOZOMI_ENDPOINT = "https://nozomi.temporal.xyz/?c=<YOUR_API_KEY>";
const NOZOMI_TIP = new PublicKey("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq");
const MIN_TIP_AMOUNT = 1_000_000;

const SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com";

async function sendNozomiTxn(ixns, signer, nozomiRpcClient, solanaRpcClient) {
    const tipIxn = SystemProgram.transfer({
        fromPubkey: signer.publicKey,
        toPubkey: NOZOMI_TIP,
        lamports: MIN_TIP_AMOUNT
    });
    ixns.push(tipIxn);

    const { blockhash } = await solanaRpcClient.getLatestBlockhash();

    const messageV0 = new TransactionMessage({
        payerKey: signer.publicKey,
        recentBlockhash: blockhash,
        instructions: ixns,
    }).compileToV0Message();

    const versionedTxn = new VersionedTransaction(messageV0);

    versionedTxn.sign([signer]);

    return await nozomiRpcClient.sendTransaction(versionedTxn);
}

function buildIxns() {
    // your instruction building logic here..
    return [];
}

async function main() {
    const nozomiRpcClient = new Connection(NOZOMI_ENDPOINT);

    const solanaRpcClient = new Connection(SOLANA_RPC_ENDPOINT);

    // replace with actual keypair loading logic
    const signer = Keypair.generate();

    const ixns = buildIxns();

    const signature = await sendNozomiTxn(ixns, signer, nozomiRpcClient, solanaRpcClient);

    console.log(`Transaction sent with signature: ${signature}`);
}

main().catch(err => {
    console.error(err);
});

Go

Made by a wonderful community member.

https://github.com/weeaa/tempgoral

Jupiter Swap Example

Github URL for Jupiter Swap Transactions.

https://github.com/temporalxyz/nozomi-examples/blob/main/typescript/jup-swap-example/jup-json-rpc.ts

Rust

Use full service RPC for fetching latest blockhash. Nozomi only supports sendTransaction.

use solana_client::rpc_client::RpcClient;
use solana_sdk::{message::Instruction, pubkey, pubkey::Pubkey, signature::Keypair, signer::Signer, transaction::Transaction};

const NOZOMI_ENDPOINT: &str = "https://nozomi.temporal.xyz/?c=<YOUR_API_KEY>";
const NOZOMI_TIP: Pubkey = pubkey!("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq");
const MIN_TIP_AMOUNT: u64 = 1_000_000;

const SOLANA_RPC_ENDPOINT: &str = "https://api.mainnet-beta.solana.com";

fn send_nozomi_txn(ixns: &mut Vec<Instruction>, signer: &Keypair, nozomi_rpc_client: &RpcClient, solana_rpc_client: &RpcClient) {
    let tip_ix = solana_system_interface::instruction::transfer(&signer.pubkey(), &NOZOMI_TIP, MIN_TIP_AMOUNT);
    ixns.push(tip_ix);

    let blockhash = solana_rpc_client.get_latest_blockhash().unwrap();
    let tx = Transaction::new_signed_with_payer(ixns, Some(&signer.pubkey()), &[signer], blockhash);

    nozomi_rpc_client.send_transaction(&tx).unwrap();
}

fn build_ixns() -> Vec<Instruction> {
    // your instruction building logic here..
    vec![]
}

fn main() {
    let nozomi_rpc_client = RpcClient::new(NOZOMI_ENDPOINT.to_string());

    let solana_rpc_client = RpcClient::new(SOLANA_RPC_ENDPOINT.to_string());

    let keypair = Keypair::new();

    let mut ixns = build_ixns();

    send_nozomi_txn(&mut ixns, &keypair, &nozomi_rpc_client, &solana_rpc_client);
}

Transaction Submission (JSON-RPC)

Nozomi sends transactions through multiple channels to achieve best performance.

sendTransaction

The Nozomi transaction submission endpoint supports the `sendTransaction` Solana JSON-RPC method. Just insert the URL where you would place a RPC URL.

Transactions are sent through 1) Self hosted nodes 2) Staked connections and 3) Jito bundles.

Auto Routed Endpoint

https://nozomi.temporal.xyz/?c=

Regioned Endpoints

Direct HTTP:

PITT:

TYO:

SGP:

EWR:

AMS:

FRA:

Secure HTTPS:

PITT:

TYO:

SGP:

EWR:

AMS:

FRA:

HTTP POST Body

Just add API Key after ?c=<uuid> to get custom URL for sending.

Regional submission endpoints are in US East, Frankfurt, Amsterdam, Singapore and Tokyo.

All boxes are run with custom hardware modifications.

Please specify base64 encoding.

Python

Use full service RPC for fetching latest blockhash.

Tip Stream

Stream Nozomi Tip Floors by Percentile

Rest Endpoint

Websocket

Python

Use full service RPC for fetching latest blockhash.. Nozomi only supports sendTransaction.

Transaction Submission (API v2)

Nozomi sends transactions through multiple channels to achieve best performance.

sendTransaction2

The /api/sendTransaction2 endpoint is not compatible with the Solana JSON-RPC sendTransaction method. Requests sent via the /api/sendTransaction2 endpoint from browser clients will see better performance, as this endpoint will skip the OPTIONS preflight request triggered by normal Solana JSON-RPC methods.

The /api/sendTransaction2

Keeping Your TCP Connection Alive

🔄 How Do I Keep the Connection Alive?

To keep your TCP connection to our server alive and avoid reconnecting, you can periodically send a simple request to the /ping endpoint.


Jupiter Swap Example

Github URL for Jupiter Swap Transactions.

endpoint does not return a transaction signature on success. A successful request will return an empty body with a
200 OK
status code.

Benefits

  • Eliminates CORS Preflight: Skips OPTIONS preflight requests that add 50-100ms latency

  • Faster Encoding: Base64 encoding/decoding is significantly faster than base58 operations

  • Reduced Body Size: Base64 encoding is more compact than base58 serialization used in JSON-RPC

  • Lower Bandwidth Usage: Smaller payloads reduce network transfer time and costs

  • Lower Network Overhead: Plain text payload avoids JSON parsing overhead

How to Use

Content-Type: text/plain HTTP Method: POST Body Format: "<YOUR_BASE_64_ENCODED_TXN_BYTES>"

Just add API Key after ?c=<uuid> to get custom URL for sending.

Endpoints (Regions)

Auto Routed: https://nozomi.temporal.xyz/api/sendTransaction2?c=

Direct HTTP:

  • PITT: http://pit1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • TYO: http://tyo1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • SGP: http://sgp1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • EWR: http://ewr1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • AMS: http://ams1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • FRA: http://fra2.nozomi.temporal.xyz/api/sendTransaction2?c=

Secure HTTPS:

  • PITT: https://pit1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • TYO: https://tyo1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • SGP: https://sgp1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • EWR: https://ewr1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • AMS: https://ams1.nozomi.temporal.xyz/api/sendTransaction2?c=

  • FRA: https://fra2.nozomi.temporal.xyz/api/sendTransaction2?c=

Regional submission endpoints are in US East, Frankfurt, Amsterdam, Tokyo, and Singapore. All boxes are run with custom hardware modifications.

https://github.com/temporalxyz/nozomi-examples/blob/main/typescript/jup-swap-example/jup-api-v2.ts
http://pit1.nozomi.temporal.xyz/?c=
http://tyo1.nozomi.temporal.xyz/?c=
http://sgp1.nozomi.temporal.xyz/?c=
http://ewr1.nozomi.temporal.xyz/?c=
http://ams1.nozomi.temporal.xyz/?c=
http://fra2.nozomi.temporal.xyz/?c=
https://pit1.nozomi.temporal.xyz/?c=
http://tyo1.nozomi.temporal.xyz/?c=
http://sgp1.nozomi.temporal.xyz/?c=
https://ewr1.nozomi.temporal.xyz/?c=
https://ams1.nozomi.temporal.xyz/?c=
http://fra2.nozomi.temporal.xyz/?c=
import aiohttp
import asyncio
import base64

from typing import List

from solders.pubkey import Pubkey
from solders.keypair import Keypair
from solders.instruction import Instruction
from solders.transaction import Transaction
from solders.system_program import transfer, TransferParams
from solders.hash import Hash

from solana.rpc.async_api import AsyncClient

NOZOMI_ENDPOINT = "https://nozomi.temporal.xyz/api/sendTransaction2?c=<YOUR_API_KEY>"
NOZOMI_TIP = Pubkey.from_string("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq")
MIN_TIP_AMOUNT = 1_000_000

SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com"

async def send_nozomi_txn(
    ixns: List[Instruction],
    signer: Keypair,
    nozomi_endpoint: str,
    solana_rpc_client: AsyncClient
) -> None:
    tip_ixn = transfer(TransferParams(
        from_pubkey=signer.pubkey(),
        to_pubkey=NOZOMI_TIP,
        lamports=MIN_TIP_AMOUNT
    ))
    ixns.append(tip_ixn)

    blockhash_resp = await solana_rpc_client.get_latest_blockhash()
    blockhash = blockhash_resp.value.blockhash

    txn = Transaction.new_signed_with_payer(
        ixns,
        signer.pubkey(),
        [signer],
        blockhash
    )

    txn_bytes = bytes(txn)
    txn_base64 = base64.b64encode(txn_bytes).decode('utf-8')

    async with aiohttp.ClientSession() as session:
        async with session.post(
            nozomi_endpoint,
            headers={"Content-Type": "text/plain"},
            data=txn_base64
        ) as response:
            # api v2 does not return a signature, just check for success
            if response.status >= 200 and response.status < 300:
                print("Transaction sent successfully")
            else:
                error_text = await response.text()
                raise Exception(f"Transaction failed with status {response.status}: {error_text}")

def build_ixns() -> List[Instruction]:
    # your instruction building logic here..
    return []

async def main():
    solana_rpc_client = AsyncClient(SOLANA_RPC_ENDPOINT)

    # replace with actual keypair loading logic
    signer = Keypair()

    ixns = build_ixns()

    await send_nozomi_txn(ixns, signer, NOZOMI_ENDPOINT, solana_rpc_client)

if __name__ == "__main__":
    asyncio.run(main())
import asyncio

from typing import List

from solders.pubkey import Pubkey
from solders.keypair import Keypair
from solders.signature import Signature
from solders.instruction import Instruction
from solana.transaction import Transaction
from solders.system_program import transfer, TransferParams

from solana.rpc.async_api import AsyncClient

NOZOMI_ENDPOINT = "https://nozomi.temporal.xyz/?c=<YOUR_API_KEY>"
NOZOMI_TIP = Pubkey.from_string("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq")
MIN_TIP_AMOUNT = 1_000_000

SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com"

async def send_nozomi_txn(ixns: List[Instruction], signer: Keypair, nozomi_rpc_client: AsyncClient, solana_rpc_client: AsyncClient) -> Signature:
    tip_ixn = transfer(TransferParams(
        from_pubkey=signer.pubkey(),
        to_pubkey=NOZOMI_TIP,
        lamports=MIN_TIP_AMOUNT
    ))
    ixns.append(tip_ixn)

    blockhash = (await solana_rpc_client.get_latest_blockhash()).value.blockhash
    txn = Transaction()

    for ixn in ixns:
        txn.add(ixn)

    # solanapy does not expose an encoding option via TxOpts
    return (await nozomi_rpc_client.send_transaction(txn, signer, recent_blockhash=blockhash)).value

def build_ixns() -> List[Instruction]:
    # your instruction building logic here..
    return []

async def main():
    nozomi_rpc_client = AsyncClient(NOZOMI_ENDPOINT)

    solana_rpc_client = AsyncClient(SOLANA_RPC_ENDPOINT)

    # replace with actual keypair loading logic
    signer = Keypair()

    ixns = build_ixns()

    signature = await send_nozomi_txn(ixns, signer, nozomi_rpc_client, solana_rpc_client)

    print(f"Transaction sent with signature: {signature}")

if __name__ == "__main__":
    asyncio.run(main())

TypeScript

Use full service RPC for fetching latest blockhash.

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

const NOZOMI_ENDPOINT = "https://nozomi.temporal.xyz/api/sendTransaction2?c=<YOUR_API_KEY>";
const NOZOMI_TIP = new PublicKey("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq");
const MIN_TIP_AMOUNT = 1_000_000;

const SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com";

async function sendNozomiTxn(
    ixns: TransactionInstruction[],
    signer: Keypair,
    nozomiEndpoint: string,
    solanaRpcClient: Connection
): Promise<void> {
    const tipIxn = SystemProgram.transfer({
        fromPubkey: signer.publicKey,
        toPubkey: NOZOMI_TIP,
        lamports: MIN_TIP_AMOUNT
    });
    ixns.push(tipIxn);

    const { blockhash } = await solanaRpcClient.getLatestBlockhash();

    const messageV0 = new TransactionMessage({
        payerKey: signer.publicKey,
        recentBlockhash: blockhash,
        instructions: ixns,
    }).compileToV0Message();

    const versionedTxn = new VersionedTransaction(messageV0);
    versionedTxn.sign([signer]);

    const txnBytes = versionedTxn.serialize();
    const txnBase64 = Buffer.from(txnBytes).toString('base64');

    const response = await fetch(nozomiEndpoint, {
        method: 'POST',
        headers: {
            'Content-Type': 'text/plain',
        },
        body: txnBase64
    });

    if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`Transaction failed with status ${response.status}: ${errorText}`);
    }

    // api v2 does not return a signature, just check for success
    console.log('Transaction sent successfully');
}

function buildIxns(): TransactionInstruction[] {
    // your instruction building logic here..
    return [];
}

async function main() {
    const solanaRpcClient = new Connection(SOLANA_RPC_ENDPOINT);

    // replace with actual keypair loading logic
    const signer = Keypair.generate();

    const ixns = buildIxns();

    await sendNozomiTxn(ixns, signer, NOZOMI_ENDPOINT, solanaRpcClient);
}

main().catch(err => {
    console.error(err);
});

Rust

Use full service RPC for fetching latest blockhash.


use solana_client::rpc_client::RpcClient;
use solana_sdk::{message::Instruction, pubkey, pubkey::Pubkey, signature::Keypair, signer::Signer, transaction::Transaction};
use base64::{Engine as _, engine::general_purpose};

const NOZOMI_ENDPOINT: &str = "https://nozomi.temporal.xyz/api/sendTransaction2?c=<YOUR_API_KEY>";
const NOZOMI_TIP: Pubkey = pubkey!("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq");
const MIN_TIP_AMOUNT: u64 = 1_000_000;

const SOLANA_RPC_ENDPOINT: &str = "https://api.mainnet-beta.solana.com";

fn send_nozomi_txn(
    ixns: &mut Vec<Instruction>,
    signer: &Keypair,
    nozomi_endpoint: &str,
    solana_rpc_client: &RpcClient
) -> Result<(), Box<dyn std::error::Error>> {
    let tip_ixn = solana_system_interface::instruction::transfer(
        &signer.pubkey(),
        &NOZOMI_TIP,
        MIN_TIP_AMOUNT
    );
    ixns.push(tip_ixn);

    let blockhash = solana_rpc_client.get_latest_blockhash()?;
    let txn = Transaction::new_signed_with_payer(
        ixns,
        Some(&signer.pubkey()),
        &[signer],
        blockhash
    );

    let txn_bytes = bincode::serialize(&txn)?;

    let txn_base64 = general_purpose::STANDARD.encode(&txn_bytes);

    let client = reqwest::blocking::Client::new();
    let response = client
        .post(nozomi_endpoint)
        .header("Content-Type", "text/plain")
        .body(txn_base64)
        .send()?;

    // api v2 does not return a signature, just check for success
    if response.status().is_success() {
        Ok(())
    } else {
        Err(Box::new(response.error_for_status().unwrap_err()))
    }
}

fn build_ixns() -> Vec<Instruction> {
    // your instruction building logic here..
    vec![]
}

fn main() {
    let solana_rpc_client = RpcClient::new(SOLANA_RPC_ENDPOINT.to_string());

    // replace with actual keypair loading logic
    let signer = Keypair::new();

    let mut ixns = build_ixns();

    if send_nozomi_txn(
        &mut ixns,
        &signer,
        NOZOMI_ENDPOINT,
        &solana_rpc_client
    ).is_ok() {
        println!("Transaction sent successfully");
    }
}
Schema
curl https://api.nozomi.temporal.xyz/tip_floor
wscat -c wss://api.nozomi.temporal.xyz/tip_stream
[
  {
    "time": "string (ISO 8601 timestamp)",
    "landed_tips_25th_percentile": "number",
    "landed_tips_50th_percentile": "number",
    "landed_tips_75th_percentile": "number",
    "landed_tips_95th_percentile": "number",
    "landed_tips_99th_percentile": "number"
  }
]
Strategy

The server supports persistent connections with a keep-alive timeout of 65 seconds. This means:

  • If your connection is idle for more than 65 seconds, it will be closed.

  • To keep it open, send any request before that timeout expires.

  • Each connection can send max 1000 requests.

We recommend using the /ping endpoint:

GET /ping

This endpoint is lightweight, fast, and designed specifically to help maintain your connection.


Suggested Interval

Send a request to /ping every 60 seconds to keep the connection alive reliably.

Example:


⚠️ Notes

  • This is not a health check — it's just a way to prevent idle disconnects

  • Avoid pinging more often than needed

{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "sendTransaction",
    "params": [ 
        "<YOUR_BASE_64_ENCODED_TXN_BYTES>",
        { "encoding": "base64" }
    ] 
}
while true; do
  curl -s http://nozomi.temporal.xyz/ping > /dev/null
  sleep 60
done

JavaScript

Use full service RPC for fetching latest blockhash.

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

const NOZOMI_ENDPOINT = "https://nozomi.temporal.xyz/api/sendTransaction2?c=<YOUR_API_KEY>";
const NOZOMI_TIP = new PublicKey("TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq");
const MIN_TIP_AMOUNT = 1_000_000;

const SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com";

async function sendNozomiTxn(ixns, signer, nozomiEndpoint, solanaRpcClient) {
    const tipIxn = SystemProgram.transfer({
        fromPubkey: signer.publicKey,
        toPubkey: NOZOMI_TIP,
        lamports: MIN_TIP_AMOUNT
    });
    ixns.push(tipIxn);

    const { blockhash } = await solanaRpcClient.getLatestBlockhash();

    const messageV0 = new TransactionMessage({
        payerKey: signer.publicKey,
        recentBlockhash: blockhash,
        instructions: ixns,
    }).compileToV0Message();

    const versionedTxn = new VersionedTransaction(messageV0);
    versionedTxn.sign([signer]);

    const txnBytes = versionedTxn.serialize();
    const txnBase64 = Buffer.from(txnBytes).toString('base64');

    const response = await fetch(nozomiEndpoint, {
        method: 'POST',
        headers: {
            'Content-Type': 'text/plain',
        },
        body: txnBase64
    });

    if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`Transaction failed with status ${response.status}: ${errorText}`);
    }

    // api v2 does not return a signature, just check for success
    console.log('Transaction sent successfully');
}

function buildIxns() {
    // your instruction building logic here..
    return [];
}

async function main() {
    const solanaRpcClient = new Connection(SOLANA_RPC_ENDPOINT);

    // replace with actual keypair loading logic
    const signer = Keypair.generate();

    const ixns = buildIxns();

    await sendNozomiTxn(ixns, signer, NOZOMI_ENDPOINT, solanaRpcClient);
}

main().catch(err => {
    console.error(err);
});

Go

Use full service RPC for fetching latest blockhash.

CURL

curl https://nozomi.temporal.xyz/api/sendTransaction2?c=<YOUR_API_KEY> \
  -X POST \
  -H "Content-Type: text/plain" \
  -d '<YOUR_BASE_64_ENCODED_TXN_BYTES>'
package main

import (
	"bytes"
	"context"
	"encoding/base64"
	"fmt"
	"io"
	"net/http"

	"github.com/gagliardetto/solana-go"
	"github.com/gagliardetto/solana-go/programs/system"
	"github.com/gagliardetto/solana-go/rpc"
)

const (
	NOZOMI_ENDPOINT     = "https://nozomi.temporal.xyz/api/sendTransaction2?c=<YOUR_API_KEY>"
	NOZOMI_TIP          = "TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq"
	MIN_TIP_AMOUNT      = 1_000_000
	SOLANA_RPC_ENDPOINT = "https://api.mainnet-beta.solana.com"
)

func sendNozomiTx(
	ctx context.Context,
	ixns []solana.Instruction,
	signer solana.PrivateKey,
	nozomiEndpoint string,
	solanaRpcClient *rpc.Client,
) error {
	nozomiTipPubkey := solana.MustPublicKeyFromBase58(NOZOMI_TIP)
	tipIxn := system.NewTransferInstruction(
		MIN_TIP_AMOUNT,
		signer.PublicKey(),
		nozomiTipPubkey,
	).Build()
	ixns = append(ixns, tipIxn)

	recentBlockhash, err := solanaRpcClient.GetLatestBlockhash(ctx, rpc.CommitmentFinalized)
	if err != nil {
		return fmt.Errorf("failed to get latest blockhash: %w", err)
	}

	tx, err := solana.NewTransaction(
		ixns,
		recentBlockhash.Value.Blockhash,
		solana.TransactionPayer(signer.PublicKey()),
	)
	if err != nil {
		return fmt.Errorf("failed to create transaction: %w", err)
	}

	_, err = tx.Sign(func(key solana.PublicKey) *solana.PrivateKey {
		if key.Equals(signer.PublicKey()) {
			return &signer
		}
		return nil
	})
	if err != nil {
		return fmt.Errorf("failed to sign transaction: %w", err)
	}

	txBytes, err := tx.MarshalBinary()
	if err != nil {
		return fmt.Errorf("failed to marshal transaction: %w", err)
	}

	txBase64 := base64.StdEncoding.EncodeToString(txBytes)

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, nozomiEndpoint, bytes.NewBufferString(txBase64))
	if err != nil {
		return fmt.Errorf("failed to create request: %w", err)
	}

	req.Header.Set("Content-Type", "text/plain")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("failed to send transaction: %w", err)
	}
	defer resp.Body.Close()

	// api v2 does not return a signature, just check for success
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("transaction failed with status %d: %s", resp.StatusCode, string(body))
	}

	fmt.Println("Transaction sent successfully")
	return nil
}

func buildIxns() []solana.Instruction {
	// your instruction building logic here..
	return []solana.Instruction{}
}

func main() {
	ctx := context.Background()

	solanaRpcClient := rpc.New(SOLANA_RPC_ENDPOINT)

	// replace with actual keypair loading logic
	signer := solana.NewWallet()

	ixns := buildIxns()

	err := sendNozomiTx(ctx, ixns, signer.PrivateKey, NOZOMI_ENDPOINT, solanaRpcClient)
	if err != nil {
		panic(err)
	}
}

Introduction

Land transactions faster and more consistently.

Nozomi is a fully custom proprietary client written by HPC and HFT engineers designed to land transactions as fast as possible.

Who Should Use It

Sniper Bots: Snipe tokens and mints before the competition.

Defi Apps: Create a better UX so user transactions do not stall or fail.

Traders: Land with speed and precision to capture the most opportunities.

Liquidators: Be first to a liquidation transaction.

Jito Bundle Users: Get through the block engine faster and more efficient.

Algorithmic traders: Get predictability with your bots in all market conditions.