Batch Send API

Use batch send to push many transactions with lower client/network overhead and faster pipeline throughput.

What this does

This document describes Lunar Lander's binary batch send endpoints, including streaming semantics and response behavior. The endpoint supports the following low latency transaction sending strategy:

  • You send a binary body containing length-prefixed transactions
  • The server starts parsing/sending transactions as bytes arrive (no need to wait for full body!)
  • Response returns a summary (attempted, accepted, rejected, parse_error) instead of per-tx signatures

Endpoints

  • POST /sendBatch

All batch endpoints require Content-Type: application/octet-stream.

Wire Format

The request body is a sequence of length-prefixed transactions:

  • frame = u16_be_length + raw_tx_bytes
  • u16_be_length is a 2-byte unsigned integer in big-endian order
  • raw_tx_bytes is the serialized Solana transaction payload

Example with three transactions:

[len1_be][tx1][len2_be][tx2][len3_be][tx3]

Streaming Semantics

Batch bodies are decoded incrementally from the HTTP body stream:

  • Each complete frame is parsed as soon as its bytes arrive
  • Each parsed transaction is processed immediately (no wait for full body)
  • Valid transactions before and after a rejected transaction are still attempted

Validation And Limits

  • Maximum transactions per request: 16
  • Minimum transaction payload size: 66 bytes
  • Maximum transaction payload size: 1232 bytes

If framing breaks (for example, truncated length prefix/payload), already parsed prefix transactions are still attempted.

Response Contract

Response is always JSON:

{
  "attempted": 3,
  "accepted": 2,
  "rejected": 1,
  "parse_error": null
}

Fields:

  • attempted: number of parsed transactions that were processed
  • accepted: number of transactions accepted by ingress validation (includes deduped signatures)
  • rejected: number of parsed transactions rejected by validation
  • parse_error: framing/stream-level error object, or null

parse_error shape:

{
  "kind": "incomplete_payload",
  "at_tx_index": 3,
  "message": "incomplete transaction payload"
}

Notes:

  • at_tx_index is 1-based
  • for framing failures, at_tx_index points to the next frame being parsed

Status codes:

  • 200 OK when rejected == 0 and parse_error == null
  • 400 Bad Request when any parsed transaction is rejected or parse_error is present

Parse Error Kinds

  • empty_body
  • incomplete_length_prefix
  • incomplete_payload
  • max_batch_exceeded
  • body_read_error
  • rate_limited