developers

Public · no key · JSON

Solana mainnet · Meteora DBC

Build on lmbo.fun

Everything the lot shows comes from the endpoints on this page: the quotes, the cars on the lot, each car's odometer and miles, the service records with a CSV per payout, each token's owners and sales, and a live trade stream. Read freely. Every answer is JSON, every path is a plain GET, and no key is issued or required. A price is never a bare number here: it comes with the quote it is in.

Base URLhttps://lmbo.fun
Example mintreading the newest listing

Read24 endpoints · GET · cached

GET /api/pairs

Quotes

The quote board. The six crypto quotes (SOL, USDC, USD1, MET, JUP, CARDS) and every xStock, one row each. kind is sol, stable, crypto or stock. open is true when the dealer has a DBC config for the quote in setting.json; a quote that is not open reads "not on the lot yet" and cannot be launched against. A stock also needs its Meteora token badge (unlocked). terms is read on-chain from that quote's config, per quote: creatorFeePct and flags, or null while unread or closed. priceUsd comes from the odometer's price cache (crypto) or the stock price sweep; stables read 1. No request waits on the chain for long: each config read has a 3 second window and a 60 second cache.

Returnsok · checkedAt · total · stockTotal · unlockedCount · openCount · terms (null) · pairs[]

Rowid · name · mint · decimals · kind · open · icon · priceUsd · terms{creatorFeePct, flags} · for stocks: unlocked · liquidityUsd · perSol · routable · autoBuy

curl -s https://lmbo.fun/api/pairs
GET /api/pairs/:symbol

One quote

One row of the board by symbol (case-insensitive for crypto, exact for stocks such as AAPLx), with config, the DBC config address a launch against this quote uses (null when the quote is not on the lot), and for a stock badge, its Meteora token badge account. A symbol not on the board answers 404 UNKNOWN_PAIR.

curl -s https://lmbo.fun/api/pairs/JUP
GET /api/pairs/:symbol/route

Route check

Asks Jupiter now whether SOL routes into the stock, so a launcher knows before signing whether a first buy can be bought inside the launch transaction (autoBuy) or the stock must be held first. Kept apart from the board so one slow answer never holds it. 503 ROUTE_UNKNOWN when the check is throttled, 502 ROUTE_CHECK_FAILED when Jupiter fails, 404 UNKNOWN_PAIR for a symbol not on the board.

Returnsok · symbol · routable · autoBuy · perSol

curl -s https://lmbo.fun/api/pairs/AAPLx/route
GET /api/deployments/list

Listings

Every token listed on this pad, newest first, up to 50 per page. page starts at 1; limit runs 1 to 50 and defaults to 20; status filters on the stored status, such as bonding; sort=old reverses the order, and any other value is newest first. pair is the quote the token trades in, pool_address its Meteora pool, tx_signature the listing transaction. Read from the database on each call.

Returnssuccess · deployments[] · total · page · limit

Rowid · mint_address · pool_address · wallet_address · name · symbol · pair · status · tx_signature · image_url · description · twitter · website · telegram · fee_mode · created_at

curl -s "https://lmbo.fun/api/deployments/list?page=1&limit=20"
GET /api/deployments/token/:mint

One listing

One listing by mint, the same row as the list. Only a token listed on this pad is answered. A mint that was never launched here, whatever it is on chain, answers 404 with {"success":false,"error":"not_listed"}, and the site shows NOT RECORDED for it. A malformed mint answers 400.

Returnssuccess · token{id, mint_address, pool_address, wallet_address, name, symbol, pair, status, tx_signature, image_url, description, twitter, website, telegram, fee_mode, created_at}

curl -s https://lmbo.fun/api/deployments/token/<mint>
GET /api/deployments/mcap?mints=

Market caps

Prices up to 30 comma-separated mints from their pools on chain and answers an object keyed by mint. priceQuote and mcapQuote are in the quote; priceUsd and mcap are in dollars at quoteUsd, the quote's cached price; quoteLabel names the quote. bondingProgress runs 0 to 100. liquidity is in dollars. feesEarned is lifetime trading fees in dollars and feesEarnedSOL the same figure in the quote, whatever the suffix says. volume24h appears when DexScreener knows the pair, totalVolume otherwise. ath is the highest market cap recorded. Cached 30 seconds per mint. A mint with no pool is left out of the answer; no mints answers {}.

Returns{<mint>: {mcap, mcapQuote, priceQuote, priceUsd, quoteLabel, quoteUsd, source, liquidity, feesEarned, feesEarnedSOL, creatorFeeSOL, platformFeeSOL, volume24h, totalVolume, isMigrated, bondingProgress, ath}}

curl -s "https://lmbo.fun/api/deployments/mcap?mints=<mint>"
GET /api/token/:mint/holders

Holders

The book. The largest holders of a listed token, read from the chain and cached 30 seconds. limit runs 1 to 200, but the RPC ranks the 20 largest accounts at most, so holders[] holds up to 20 rows and truncated says whether more exist. Each row carries owner, account, amount in whole units, amountRaw in base units, share in percent of supply, and a label where the owner is the bonding curve or the creator (pass creator=<wallet> to label it). holderCount counts every account with a balance when the RPC can count them, and countExact says whether it could. curve states the pool in its quote: quoteSymbol, quoteUsd, migrationThreshold in the quote, progress from 0 to 1, the price and market cap in the quote and in dollars, isMigrated. 400 INVALID_MINT; a mint not listed here answers 404 NOT_LISTED.

Returnsok · mint · decimals · supply · circulating · holderCount · countExact · walletCount · truncated · rankable · curveHeld · pool · curve{quoteMint, quoteSymbol, quoteIsSol, quoteUsd, baseReserve, quoteReserve, migrationThreshold, progress, priceQuote, priceUsd, mcapQuote, mcapUsd, liquidityUsd, totalSupply, isMigrated, creator} · holders[]

Rowrank · owner · account · amount · amountRaw · share · label

curl -s "https://lmbo.fun/api/token/<mint>/holders?limit=20"
GET /api/token/:mint/trades

Trades

The tape. Recent trades against the token's pool, read from the chain, newest first, up to 100 with limit (default 30), cached 20 seconds. Each row is the trader's own balance change in that transaction: side is buy or sell, baseAmount is in the token, quoteAmount in the quote, price the quote per unit, blockTime Unix seconds. quoteMint and quoteDecimals name the quote the pool trades in. A mint not listed here answers 404 NOT_LISTED.

Returnsok · mint · pool · quoteMint · quoteDecimals · quoteIsSol · trades[]

Rowsignature · blockTime · side · trader · baseAmount · quoteAmount · price

curl -s "https://lmbo.fun/api/token/<mint>/trades?limit=30"
GET /api/deployments/trades/:mint

Swap history

Swaps touching the mint as Helius indexes them, up to 50 with limit (default 30), cached 30 seconds. type is buy, sell or swap (an aggregator route where the fee payer is not the trader); tokenAmount is in the token; solAmount is the SOL or wrapped SOL moved, which on a pool quoted in anything but SOL is usually 0; timestamp is Unix seconds. This is the older read the site kept from SOL pairs. For amounts in the quote use /api/token/:mint/trades. A Helius failure answers 200 with an empty trades, and solPrice is present only on a fresh, successful read.

Returnssuccess · trades[] · solPrice

Rowtype · tokenAmount · solAmount · wallet · timestamp · signature

curl -s "https://lmbo.fun/api/deployments/trades/<mint>?limit=30"
GET /api/deployments/total-fees

Lifetime fees

The sum of lifetime trading fees across every pool this pad has listed, as the stats strip shows it, cached 5 minutes. totalFeesSOL reads each pool's raw fee at 9 decimals as SOL, or at 6 decimals for a USD1 or USDC pair converted at solPrice. A stock-quoted pool collects its fee in the stock at 8 decimals, so on this pad the figure is a headline count rather than a sum in one currency. poolsScanned is the number of pools that answered.

Returnssuccess · totalFeesSOL · poolsScanned · solPrice

curl -s https://lmbo.fun/api/deployments/total-fees
GET /api/activity/feed

Fee ledger

The fee ledger for every token: each claim, holder payout and buyback the platform has recorded in the last 30 days, newest first. limit defaults to 30 and caps at 100; type filters on creator_claim, holder_distribute or buyback. amountSOL is the amount in the pool's quote token as the job recorded it; the name keeps its SOL suffix from the SOL-pair days. details carries holdersCount on a payout and tokensReceived on a buyback. Empty until the first payout runs.

Returnssuccess · feed[]

Rowid · type · timestamp · tokenMint · tokenSymbol · tokenName · poolAddress · amountSOL · signature · solscanUrl · details{}

curl -s "https://lmbo.fun/api/activity/feed?limit=30"
GET /api/activity/trades

Recent trades

The site-wide tape as the sales log on the Lot shows it: the last trades the live watcher has seen on any listed pool, newest first, limit default 20 and at most 50. The buffer holds 50 trades in memory, so it is empty after a restart until the next trade lands. wallet is the trader shortened, walletFull the address, solAmount the trader's SOL balance change (0 when the trade is paid in another quote), timestamp the time the watcher saw it, as ISO 8601. The same rows arrive pushed on the trade stream below.

Returnssuccess · trades[]

Rowtype · symbol · mint · wallet · walletFull · solAmount · timestamp · signature

curl -s "https://lmbo.fun/api/activity/trades?limit=20"
GET /api/activity/token/:mint

Token ledger

The fee ledger for one token, the same rows as the feed, newest first, limit default 20 and at most 100. A mint shorter than 20 characters answers 400; any other string answers 200 with an empty list, listed here or not.

Returnssuccess · activities[]

Rowid · type · timestamp · tokenMint · tokenSymbol · tokenName · poolAddress · amountSOL · signature · solscanUrl · details{}

curl -s "https://lmbo.fun/api/activity/token/<mint>?limit=20"
GET /api/activity/stats/:mint

Fee stats

The ledger for one token summed: the amounts claimed, paid to holders and bought back, the count of each, the holders reached, the tokens bought back, and the time of the last entry. All zero and lastActivity null for a token with no entries.

Returnssuccess · stats{totalClaimedSOL, totalDistributedSOL, totalBuybackSOL, claimCount, distributionCount, buybackCount, lastActivity, totalHoldersReached, totalTokensBoughtBack}

curl -s https://lmbo.fun/api/activity/stats/<mint>
GET /api/leaderboard

Leaderboard

The listed tokens ranked. sort=mcap (the default) orders by market cap in dollars, sort=new by listing time; limit runs 1 to 100, default 25. Each row carries the listing and, where the live pool tracker has priced it, mcap, liquidity and feesEarned in dollars with quoteLabel naming the quote; a row the tracker has not priced keeps those null and sorts last. age is a short label such as 2h, athMcap the highest market cap recorded. Cached 20 seconds. 502 LEADERBOARD_FAILED when the listings cannot be read.

Returnsok · sort · total · count · rows[]

Rowrank · mint · name · symbol · image · pair · pool · creator · status · createdAt · age · athMcap · mcap · liquidity · feesEarned · quoteLabel · isMigrated

curl -s "https://lmbo.fun/api/leaderboard?sort=mcap&limit=25"
GET /api/odometer

The Lot's odometers

Every car the odometer has counted, with its lifetime volume in dollars and its mile. sort is volume (the default), mile or new; limit runs 1 to 200, default 50. mile is where the odometer stands: index, label (START, MILE 1 to MILE 7, LAMBO, LAMBO +1 and on), prevAt and nextAt in dollars, progress from 0 to 1 between them. mileReached is true while the car is past the mile of its last payout, which is to say due for service. The odometer only reads: its runner indexes swaps and prices, and signs nothing. Cached 15 seconds per car. Served to this origin only (it is not on the open CORS list below).

Returnsok · odometers[]

Rowmint · volumeUsd · swaps · mile{index, label, prevAt, nextAt, progress} · lastDistributedMile · mileReached

curl -s "https://lmbo.fun/api/odometer?sort=volume&limit=50"
GET /api/odometer/:mint

One odometer

The odometer of one car, the same row as above. A mint the odometer has not counted answers with volumeUsd 0 at START. 400 BAD_MINT for anything that is not a base58 address.

Returnsok · odometer{mint, volumeUsd, swaps, mile, lastDistributedMile, mileReached}

curl -s https://lmbo.fun/api/odometer/<mint>
GET /api/odometer/schedule

The mile table

The miles the odometer runs on, read from the dealer's settings on every call: miles in dollars, the last one being LAMBO, and lapUsd, the dollars of each lap past LAMBO. The defaults are $5,000, $10,000, $25,000, $50,000, $100,000, $250,000, $500,000 and LAMBO at $1,000,000, then a lap every $1,000,000.

Returnsok · miles[] · lapUsd · labels[]

curl -s https://lmbo.fun/api/odometer/schedule
GET /api/records

Service records

Every payout the dealer has started (sending, done or partial), newest first, and every claim of the fee share. mint narrows both to one car; limit runs 1 to 200, default 50. Amounts are raw base units as strings: amount_raw is the payout in the quote, at quote_decimals. snapshot_hash is the sha256 over the sorted owner:rawBalance lines of the snapshot. mile_index is the mile the payout serviced. A draft, or a payout that never started sending, is not listed.

Returnsok · distributions[] · claims[]

Distributionid · mint · quote_mint · quote_decimals · token_decimals · amount_raw · paid_raw · credited_raw · mode · min_hold_raw · min_payout_raw · include_creator · status · snapshot_at · snapshot_hash · holder_count · mile_index · note · created_at

Claimid · mint · venue (dbc | damm_v2) · quote_mint · raw · signature · created_at

curl -s "https://lmbo.fun/api/records?limit=50"
GET /api/records/:id

One record

One payout and every owner's line in it: the balance at the snapshot, the share, any credit carried in from an earlier payout below the minimum, what was paid, the status (paid, pending, failed, credited) and the signature. 404 NOT_FOUND for an id that is not a counted payout.

Returnsok · distribution{…as above} · payouts[{owner, balance_raw, share_raw, credit_in_raw, pay_raw, status, signature}]

curl -s https://lmbo.fun/api/records/<id>
GET /api/records/:id/csv

A record's CSV

The same lines as a CSV, one per owner, sorted by owner: owner,balance_raw,share_raw,credit_in_raw,pay_raw,status,signature. Everything needed to recompute the split: in a proportional payout each share is amount_raw × balance_raw ÷ Σ balance_raw rounded down, with the remainder to the largest owner, and the shares add up to amount_raw exactly.

Returnstext/csv

curl -s https://lmbo.fun/api/records/<id>/csv
GET /api/site-config

Site config

The pad's identity as the front end reads it: brand name, tagline, domain and the public links. A link not set is an empty string. theme is null on this pad.

ReturnsbrandName · brandTagline · brandDomain · twitterUrl · telegramUrl · docsUrl · githubUrl · npmUrl · theme

curl -s https://lmbo.fun/api/site-config
GET /api/health

Health

Liveness. Says whether the process answers and whether its parts are configured, not what they are. status is ok whenever the server is up.

Returnsstatus · meteoraInstalled · configExists · rpcConfigured

curl -s https://lmbo.fun/api/health
GET /api/sol-price

SOL price

Jupiter's price for SOL, passed through as Jupiter answers it: one object keyed by the wrapped SOL mint with usdPrice, priceChange24h in percent, liquidity in dollars, decimals and blockId. Not cached here; nothing on the lot waits on it.

Returns{So11111111111111111111111111111111111111112: {usdPrice, priceChange24h, liquidity, decimals, blockId, createdAt}}

curl -s https://lmbo.fun/api/sol-price

Live1 stream · server-sent events

SSE /api/activity/trades/stream

Trade stream

idle

The tape, pushed. A GET that stays open as text/event-stream. No event names are used: every event is a plain message whose data is one JSON object. The first is {"type":"connected"}. If the watcher's buffer holds trades, the next is {"type":"batch","trades":[...]} with up to the last 15, newest first. After that, one event per trade as it lands, with type as buy or sell and the same fields as a recent-trades row. A comment line :keepalive is written every 30 seconds to hold the connection open; a client sees nothing for it. One open stream counts once against the rate limit.

Events{type: "connected"} · {type: "batch", trades[]} · {type: "buy" | "sell", symbol, mint, wallet, walletFull, solAmount, timestamp, signature}

curl -s -N https://lmbo.fun/api/activity/trades/stream

Transactnot published

Launch and trade

on the lot, with your wallet

Launching and trading happen on the site with your own wallet. A public prepare/submit API is not published yet.

A listed token trades on its Meteora pool, at pool_address in its listing; once it graduates it trades on Jupiter and any Solana DEX. Open the lot →

Termsno key · any origin

Rate limits & terms

#limits

5,000 requests an hour, no key

One limit covers everything under /api/, per client address, in a 60-minute window. The count and the time left are in the response headers of every answer. Over the limit, every request answers 429 with {"error":"Too many requests, try again later"} until the window resets.

Requests
5,000 per 60 minutes per IP
Scope
every path under /api/
Headers
RateLimit-Limit · RateLimit-Remaining · RateLimit-Reset · RateLimit-Policy
Over the limit
429 · {"error":"Too many requests, try again later"}
Key
none
Methods
GET
CORS
any origin · no credentials · preflight cached 600 s
Attribution
data by lmbo.fun

Cached server-side

Most reads answer from a cache, so a page that polls cannot turn into chain load. The figures below are how stale an answer can be.

PathAnswers fromCache
/api/pairs, /api/pairs/:symbolthe badge sweep and the price and route sweeps60 s · 5 min
/api/pairs/:symbol/routeJupiter, livenone
/api/deployments/list, /token/:mintthe databasenone
/api/deployments/mcapthe chain, per mint30 s
/api/deployments/trades/:mintHelius, per mint30 s
/api/deployments/total-feesthe chain, every pool5 min
/api/token/:mint/holdersthe chain30 s
/api/token/:mint/tradesthe chain20 s
/api/activity/feed, /token/:mint, /stats/:mintthe ledger on disknone
/api/activity/trades, /trades/streamthe watcher's buffer in memorylive
/api/leaderboardthe database and the pool tracker20 s
/api/odometer, /api/odometer/:mintthe odometer's running totals15 s
/api/odometer/schedulethe dealer's settingsnone
/api/records, /:id, /:id/csvthe service recordsnone
/api/sol-priceJupiter, livenone
/api/site-config, /api/healththe processnone

Terms

Read at any volume under the limit, for any purpose, and show data by lmbo.fun where the numbers appear. The open CORS rule (any origin, GET, no credentials) covers every read path on this page: /api/pairs, /api/deployments/list, /api/deployments/token, /api/deployments/mcap, /api/deployments/trades, /api/deployments/total-fees, /api/token, /api/activity, /api/leaderboard, /api/site-config, /api/health, /api/sol-price and /api/records. The odometer paths answer this origin only.

Prices come from Jupiter and can lag by the cache above. A market cap in dollars is the market cap in the quote at the quote's cached price; when the quote has no price, the dollar figures are null and the figures in the quote stand. A mint that was never listed on this pad is not described here and answers 404. Amounts on the wire are in whole units of the token or the quote, never in raw base units, except where a key ends in Raw. Nothing on this page is investment advice. Paths and keys can gain fields; a field is not removed without notice on this page.

JavaScript, no dependencies

fetch · EventSource

Read the board, price a car, read its odometer, watch the tape

Two examples, each runnable as written in a browser console or a modern Node. Nothing to install.

Fetch

const base = 'https://lmbo.fun';

// The board: every quote, and which ones are on the lot.
const board = await fetch(base + '/api/pairs').then((r) => r.json());
const open = board.pairs.filter((p) => p.open && (p.kind !== 'stock' || p.unlocked));
console.log(open.length + ' of ' + board.total + ' quotes on the lot');

// The newest car on the lot, priced in its quote.
const list = await fetch(base + '/api/deployments/list?limit=1').then((r) => r.json());
const mint = list.deployments[0].mint_address;
const caps = await fetch(base + '/api/deployments/mcap?mints=' + mint).then((r) => r.json());
const row = caps[mint];
console.log(row.priceQuote + ' ' + row.quoteLabel + ' per unit, ' + row.bondingProgress + '% of the curve');

// Its odometer, and its service book.
const odo = await fetch(base + '/api/odometer/' + mint).then((r) => r.json());
console.log('$' + Math.floor(odo.odometer.volumeUsd) + ' on the odometer, ' + odo.odometer.mile.label);
const book = await fetch(base + '/api/records?mint=' + mint).then((r) => r.json());
console.log(book.distributions.length + ' service stamps, each with a csv at /api/records/:id/csv');

// The book and the tape for that listing.
const holders = await fetch(base + '/api/token/' + mint + '/holders?limit=20').then((r) => r.json());
const trades = await fetch(base + '/api/token/' + mint + '/trades?limit=30').then((r) => r.json());
console.log(holders.holderCount + ' holders, ' + trades.trades.length + ' trades, quoted in ' + holders.curve.quoteSymbol);

Live feed

const feed = new EventSource(base + '/api/activity/trades/stream');

feed.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.type === 'connected') return;                              // the first event
  if (msg.type === 'batch') { msg.trades.forEach(print); return; }   // the last 15, once
  print(msg);                                                        // then one trade per event
};

// The browser reconnects on its own after a drop. The server writes a
// ":keepalive" comment every 30 seconds; it never reaches onmessage.
feed.onerror = () => console.log('reconnecting');

function print(t) {
  // t.type is 'buy' or 'sell'; t.solAmount is the trader's SOL balance change
  console.log(t.timestamp, t.type.toUpperCase(), t.symbol, t.wallet, t.signature);
}