betterERCLaunchpad
StandardsRobinhood Chain4663
Terminal integration

Terminal API

Every launch this launchpad has put on Robinhood Chain, as exact, versioned JSON. Discovery, market history, account views, executable quotes, unsigned transactions and a live stream. A terminal signs with its own user’s wallet; this service never accepts a private key, a signed transaction or custody of anything.

Base URLhttps://launchpad.bettererc.org/v1
OpenAPI 3.1
Chain4663Robinhood Chain
Settled at20confirmations deep
Anonymous rate60requests per minute, per IP
Live gatesTradingLaunches

Start here

Nothing is required to read. Point a request at the index and it answers with the canonical links for everything else.

Shell
curl https://launchpad.bettererc.org/v1

curl 'https://launchpad.bettererc.org/v1/tokens?sort=volume1h&order=desc&limit=25'

/v1/config is the source of truth for deployed contract addresses, ABIs, the shared Uniswap v4 pool key and the launch profile every token is created against. Read it at start up and cache it for five minutes. Do not hard-code an address out of this page.

Every launch shares one immutable pool profile: native ETH is currency0, the token is currency1, and the pool exists from the launch transaction onward. There is no bonding curve, no second venue and no migration step, so a terminal that models graduating launchpads has nothing to bind a graduation state to.

Reading a response

Every successful response carries the same envelope, and the envelope always says how far behind the chain the answer is.

Response
{
  "data": { },
  "meta": {
    "chainId": 4663,
    "indexedBlock": "41893204",
    "indexedAt": "2026-08-21T10:41:12.000Z",
    "headBlock": "41893224",
    "confirmations": 20,
    "lagSeconds": 4,
    "stale": false
  }
}

indexedBlock is the deepest block folded into the answer, and it trails headBlock by confirmations by design. When stale is true the indexer has fallen further behind than its configured tolerance and the response should be treated as a last known good value rather than a current one.

Paginated endpoints add a page block.

Response
{
  "data": [ ],
  "page": { "nextCursor": "opaque-value-or-null", "hasMore": true },
  "meta": { }
}

Errors replace the envelope with a stable code. Match on the code, never on the message.

Response
{
  "error": {
    "code": "TOKEN_NOT_FOUND",
    "message": "No launch is indexed at that address",
    "details": { "address": "0x..." }
  }
}
Raw amountsstring
Every on-chain quantity is a base-10 integer in the asset’s smallest unit. ETH and launch tokens both use 18 decimals. Parsing one as a JavaScript number loses value silently above 253.
Decimal fieldsstring
Convenience values such as priceEthPerToken and marketCapEth are formatted for display. The raw amounts beside them remain authoritative.
Addressesstring
Case-insensitive in requests, normalised to lowercase in indexed responses.
Cursorsstring
Opaque. Do not read, construct or persist one across a sort change; a cursor is bound to the sort and order it was issued under.
Unknown fieldsany
Additive and backward-compatible. Ignore what you do not recognise. Breaking changes ship under a new path version.

Common codes are INVALID_ADDRESS, INVALID_CURSOR, INVALID_PARAMETER, INVALID_API_KEY, SCOPE_DENIED, ORIGIN_DENIED, TOKEN_NOT_FOUND, AMOUNT_EXCEEDS_RANGE, NO_EXECUTABLE_QUOTE, RATE_LIMITED, FEATURE_DISABLED, INDEXER_STALE and RPC_UNAVAILABLE.

Keys and limits

Reads are open. A partner key raises the ceiling and unlocks the transaction builders, and nothing else.

Request
Authorization: Bearer berc_live_...
Anonymousno header
60 requests per minute per IP. Read scope only. Page size caps at 200.
Partnerbearer key
A per-key limit, a scope set drawn from read, tx and metadata, and an optional origin allowlist. Page size caps at 500.

Keys are SHA-256 hashed before storage, so the plaintext is shown once at issue and never again. A browser request that sends an Origin header alongside a partner key must send an origin registered on that key. A server-to-server terminal registers no origins at all.

A key grants rate and endpoint scope. It never authorises an on-chain action. A transaction builder returns calldata that still needs the user’s wallet signature.

Response headers
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset
Retry-After            only on 429

Endpoints

The full contract, with request and response schemas, is served as OpenAPI 3.1 at /v1/openapi.json.

Reference

GET/v1Service index and canonical links.
GET/v1/configChain, contracts, ABIs, pool key template, launch profile and live feature gates.
GET/v1/standardsBERC standards, extensions, conflicts and roles.
GET/v1/openapi.jsonThe machine-readable contract.

Tokens and market data

GET/v1/tokensFiltered, sorted, cursor-paginated launch list.
POST/v1/tokens/batchResolve up to 100 addresses, or 250 on a partner key.
GET/v1/tokens/{address}One launch. Accepts include=holders,trades.
GET/v1/tokens/{address}/tradesIndexed fills, newest first.
GET/v1/tokens/{address}/holdersHolders ranked by exact numeric balance, with a concentration summary.
GET/v1/tokens/{address}/transfersRaw ERC-20 transfers, optionally filtered by account.
GET/v1/tokens/{address}/candlesOHLCV from 1m to 1d.

Accounts

GET/v1/accounts/{address}/holdingsExact balances and their current ETH value.
GET/v1/accounts/{address}/tradesFills across every listed launch.
GET/v1/accounts/{address}/launchesLaunches created by the account.
GET/v1/accounts/{address}/feesCreator fee accrual, claimable amounts and the position id a claim needs.
GET/v1/accounts/{address}/pnlAverage-cost, ETH-denominated profit and loss.

Trading

GET/v1/quoteSimulate an exact-input Uniswap v4 quote.
POST/v1/tx/buyUnsigned buy calldata. Requires the tx scope.
POST/v1/tx/sellUnsigned sell calldata, with an approval step when allowance is short.
POST/v1/tx/launchUnsigned launch calldata and the predicted token address.
POST/v1/tx/claim-feesUnsigned creator fee collection calldata.

Streaming

GET/v1/stream/sseLaunches, fills, prices, candles and reorgs over Server-Sent Events.

Discovery

The token list is the endpoint a new-pairs pane and a trending board are both built on.

Shell
curl 'https://launchpad.bettererc.org/v1/tokens?sort=volume1h&order=desc&limit=50'
sortenum
launchedAt, volume24h, volume1h, volume5m, marketCap, raised, holders, progress, lastTradeAt, trades24h. Defaults to launchedAt.
orderasc | desc
Defaults to desc.
standardberc-20 | berc-721
Filter by token standard.
verifiedboolean
Whether the clone still matches the runtime it claims.
creatoraddress
Restrict to one deployer.
qstring
Free text across name and symbol.
minMarketCapEth · maxMarketCapEth · minVolume24hEthdecimal
Decimal ETH, converted server-side. Not wei.
minHolders · minProgressnumber
Holder floor, and how far through the seeded range the pool has been walked, from 0 to 1.
launchedAfter · launchedBeforeRFC 3339
Bound the launch window.
limit · cursornumber · string
50 by default, 200 anonymous, 500 on a partner key.

Trade and transfer history additionally accept since and until, each of which takes either an indexed block number or an RFC 3339 timestamp. This is the pair to backfill with.

Shell
curl 'https://launchpad.bettererc.org/v1/tokens/0x.../trades?since=41890000&limit=200'

curl 'https://launchpad.bettererc.org/v1/tokens/0x.../candles?interval=5m&quote=eth&limit=1000'

Candles omit empty buckets. Carry the previous close forward if a chart library needs continuous bars. A fill’s maker is the end user who sent the transaction and router is the contract that swapped, so a terminal attributing its own flow filters on router.

An operator can hide a token from public discovery. Hidden addresses never appear in lists or account aggregates, but their direct token endpoint stays available and returns "listed": false, so an audit trail is never broken by a listing decision.

Quotes and transactions

A quote is a simulation against the deployed v4 quoter. A builder turns that quote into calldata. Neither one moves anything.

Shell
curl 'https://launchpad.bettererc.org/v1/quote?token=0x...&side=buy&amountIn=1000000000000000000&slippageBps=500'

The response carries the exact amountOut, a slippage-adjusted minAmountOut, quoter gas, the current directional Uniswap protocol fee, the 1.25% LP fee breakdown, the effective execution price and price impact. Fee amounts are estimates because v4 rounds per swap step; the quoted output is the executable result.

A buy that would exhaust the seeded range returns AMOUNT_EXCEEDS_RANGE. A sell with no executable path returns NO_EXECUTABLE_QUOTE.

Shell
curl -X POST 'https://launchpad.bettererc.org/v1/tx/buy' \
  -H 'Authorization: Bearer berc_live_...' \
  -H 'Content-Type: application/json' \
  -d '{
    "token": "0x...",
    "recipient": "0x...",
    "amountInWei": "1000000000000000000",
    "minTokensOut": "3999500000000000000000000",
    "deadlineSeconds": 600
  }'
Response
{
  "chainId": 4663,
  "to": "0x...",
  "data": "0x...",
  "value": "1000000000000000000",
  "gasLimit": "350000",
  "function": "buy(address,address,uint256,uint256)",
  "expiresAt": "2026-08-21T10:51:00.000Z"
}

Verify chainId, show the transaction to the user, sign it with the user’s wallet and broadcast it through your own RPC. Every builder requires a partner key with the tx scope, and refuses with FEATURE_DISABLED while the matching release gate is off.

POST /v1/tx/sell
Takes token, amountIn, minNativeOut, recipient, and an optional owner and deadlineSeconds. When allowance is short the response carries an approval.transaction that must confirm first. The router uses a plain ERC-20 transferFrom, so Permit2 is not on this path.
POST /v1/tx/launch
Takes creator, name, symbol, metadataUri, and optionally salt, initialBuyWei, minInitialTokensOut and deadlineSeconds. Omit the salt and the server generates and returns one. The response also carries predictedTokenAddress and, when an initial buy is requested, initialBuyQuote.
POST /v1/tx/claim-fees
Takes tokenId, creator and recipient. The locker position is read first and a mismatched creator is rejected rather than handed calldata that would revert.

Terminals pin their own metadata and pass an immutable ipfs:// URI. The indexer fetches that document, within a 256 KiB ceiling, and reads description, image, external_url and properties.socials from it, so a launch created through a terminal renders completely on the betterERC site without touching the site’s domain-bound upload route.

Live updates

One Server-Sent Events connection carries up to twenty subscriptions, and every event is replayable.

Request
GET https://launchpad.bettererc.org/v1/stream/sse?channels=launches,prices,trades:0x...,candles:0x...:5m,reorg
Accept: text/event-stream
launchesevent: launch
A new token, in the shape the single-token endpoint returns.
trades:{token}event: trade
One fill against that token.
pricesevent: price
Batched tick and price movement.
candles:{token}:{interval}event: candle
The current bar, on every update.
reorgevent: reorg
A rewind, and the tokens it touched.

Subscribe to reorg. When the chain reorganises, rows at or above the rewind block are removed from the index, and a terminal that never hears about it keeps showing fills that no longer exist.

Every event carries an opaque id. A browser replays it automatically as Last-Event-ID on reconnect; any other client should persist that id and send the header itself. The server writes comment heartbeats while idle. The stream is backed by the same canonical index as the REST endpoints, so it respects the same 20-confirmation boundary and is not a mempool feed.

Caching and CORS

Config and standardsmax-age=300
Plus stale-while-revalidate=600. Read once at start up.
Token lists and account valuesmax-age=5
Plus stale-while-revalidate=30.
Trades, holders, transfers, candlesmax-age=2
Short enough to poll, long enough to absorb a burst.
Quotes and transaction buildersno-store
Never cached anywhere.

Anonymous responses send Access-Control-Allow-Origin: * without credentials. A partner browser request has its origin echoed only after it matches the key’s allowlist. Rate limit headers are exposed to browser clients in both cases.

What v1 does not do

Four things a terminal will look for and not find. Each is a deliberate boundary rather than an oversight.

USD pricinggated
quote=usd returns FEATURE_DISABLEDuntil an ETH/USD observation source is configured. ETH-denominated candles, values and volumes are fully available without it.
Complete PnLtransferAware: false
Cost basis is average-cost over indexed fills. Transfers and airdrops receive none. Compare walletBalance with tradeModelBalance before presenting the number as complete.
WebSocket and webhooksnot in v1
Server-Sent Events is the only push transport. Fan-out over WebSocket and signed webhooks are not part of this version.
Unconfirmed stateby design
Nothing is served before it is 20 confirmations deep. A terminal that wants pending fills reads its own RPC.

The design rationale behind these choices, and the long-term shape of the integration, is recorded alongside the service in docs/TERMINAL_API.md. To have a key issued, or to raise a limit, talk to the operator running this deployment.