psst
Docs / developer api / v1

build on psst.

A free, open JSON API with everything psst knows: circles filling, live coins, every member, every delivery, every payday and every take home send. No key, no sign up. Every request below is live, so press Send and you get real data.

Base
/api/v1
JSON over HTTPS
Methods
GET
read only
Key
none
CORS open
Times
unix ms
header x-psst-api: 1
01 / api

basics.

Base URLhttps://psstprivacy.xyz/api/v1
Read onlyEvery endpoint is GET and returns JSON. Starting a coin, taking a spot or setting take home happens with your wallet on the site.
OpenNo key. CORS is open, so you can call it from a browser, a bot or a server.
Version headerEvery v1 response carries x-psst-api: 1.
UnitsSOL as plain numbers, times as unix milliseconds, raw token amounts as strings (coin tokens have 6 decimals; pay coins use payCoin.decimals), addresses as base58.
StableFields under v1 won't be renamed or removed. New fields may be added.
02 / api

endpoints, live.

Ids, mints and wallets are prefilled from the live API, so every Send works as is.

list coins

cached 5s
/api/v1/coins

Every coin, newest first. Filter by status to watch circles filling or coins going live. Drafts that never paid the start fee aren't listed.

Returns{ coins: Coin[], count, updatedAt }

GET/api/v1/coins
curl -s "https://psstprivacy.xyz/api/v1/coins"

get a coin

cached 3s
/api/v1/coins/{id}

One coin with every detail list: the circle (every wallet, what it paid, accepted, refunded, tokens, delivery tx, linked), every payday with the goal that set it off and its claim, swap and transfer transactions, every take home send, every burn, every payment and the top 50 holders.

ReturnsCoin plus buyers, linkedPairs, paydays, takeHome, burns, joins, holderList

GET/api/v1/coins/coin%20id
curl -s "https://psstprivacy.xyz/api/v1/coins/coin%20id"

look up a mint

cached 3s
/api/v1/coins/mint/{mint}

Is this token a psst coin? Returns the full coin with isPsst: true, or a 404 with isPsst: false. Made for terminals and bots that see a token address first.

Returns{ isPsst: true, ...Coin with detail lists } or 404 { error, isPsst: false }

GET/api/v1/coins/mint/token%20mint
curl -s "https://psstprivacy.xyz/api/v1/coins/mint/token%20mint"

look up a wallet

cached 10s
/api/v1/wallets/{address}

Every coin a wallet started, joined or holds: what it put in, what was accepted and refunded, its tokens, whether it held at the last payday, its hold streak and its starter lock, next to each coin's totals. Unknown wallets come back with empty lists, not a 404.

Returns{ wallet, totals: { coinsStarted, coinsJoined, solIn, solAccepted, solRefunded }, coins: [...], updatedAt }

GET/api/v1/wallets/wallet%20address
curl -s "https://psstprivacy.xyz/api/v1/wallets/wallet%20address"

leaderboard

cached 30s
/api/v1/leaderboard

Three lists of up to 20 rows: live coins ranked by fees returned (paid to holders plus bought back and burned), the biggest circles, and the starters with the most coins live.

GET/api/v1/leaderboard
curl -s "https://psstprivacy.xyz/api/v1/leaderboard"

stats

cached 15s
/api/v1/stats

Totals across psst: coins by status, SOL that went into live coins' pots, wallets that bought in at go live, and creator fees paid to holders.

GET/api/v1/stats
curl -s "https://psstprivacy.xyz/api/v1/stats"

rules

cached 5m
/api/v1/rules

The constants every coin runs on (spots, spot price, payday goal limits, fees, payout thresholds, pay coins, curve) and the LaunchLab program and psst platform addresses. Read from the same file the server enforces.

ReturnsSee the rules object below.

GET/api/v1/rules
curl -s "https://psstprivacy.xyz/api/v1/rules"

take home, read only

cached never
/api/home

Where a wallet's Zcash payouts go and what is waiting for it on every Zcash coin. Same origin, not versioned and not cached; setting the address needs a wallet signature on the take home page, so this API never changes anything.

Returns{ wallet, to (Zcash address or null), since, coins: [{ id, ticker, waitingSol, carriedSol, sent: [{ at, sol, zecOut, tx, to, status }] }] }

GET/api/home
curl -s "https://psstprivacy.xyz/api/home"
03 / api

the coin object.

What /coins returns per coin. Single coin and mint lookups add the detail lists below.

FieldTypeMeaning
id, urlstringCoin id and its coin page.
name, ticker, descriptionstringAs set by the starter. Ticker is uppercase, 2 to 10 characters.
imagestringAbsolute URL to the coin image.
linksobjectwebsite, twitter, telegram and tweet, each a URL or null.
statusstringSee the lifecycle below.
starteraddressWallet that started the coin.
potaddressThe coin's pot address. Circle payments go here, it creates the pool on chain, claims the fee, pays holders and keeps the burn vault.
mint, pooladdress | nullNull until the coin goes live. The mint is never revealed early.
createdAt, opensAt, closesAt, launchedAt, scheduledForunix ms | nullDrafted, circle opened, circle deadline, went live, and the requested start of a scheduled coin.
startstringcircle or instant.
spotPriceSolnumber | nullSOL per spot. Null on instant coins.
spotsTaken, spotsTotalnumber | nullSpots taken out of 20. Null on instant coins.
potSolnumberSOL in the pot. Live while the circle fills, then the amount that bought.
walletsnumberWallets in the pot (the circle, or the starter on an instant coin).
entryPriceSolnumber | nullSOL per token everyone in the pot paid.
tokensBoughtstring | nullRaw token amount the pot bought (6 decimals).
launchTxsignature | nullThe block zero transaction that created the pool and bought.
failReason, lookalikeOfstring | nullWhy a coin refunded; the ticker of an earlier coin this one looks like.
feeModestringholders, burn or split.
payCoinobject{ key, symbol, name, mint, decimals, takeHome }: zec or xmr, its SPL mint on Solana, and whether take home is possible.
paidCoinstringRaw pay coin units that reached holders, all paydays (use payCoin.decimals).
feesPaidSolnumberCreator fee SOL routed to holders across all paydays (swapped, sent home or carried).
carriedSolnumberSOL waiting in the pot for holders whose shares were too small to send yet.
takeHomeWaitingSol, takeHomeSentSolnumberTake home SOL still collecting, and SOL already sent through NEAR Intents.
holdersnumber | nullWallets holding the coin at the last payday.
burnVaultSol, burnSavedTargetSolnumberSOL saved toward the next burn, and the burn target.
burnedSol, burnedTokensnumber, stringSOL spent on buybacks, and raw tokens burned.
goalsobjectThe coin's payday goals and how close it is to each. See payday goals below.
starterLockobject | null{ days, totalTokens, releasedTokens } when the starter locked their tokens.
marketobject | nullLive LaunchLab curve: priceSol, marketCapSol, raisedSol, goalSol, progress (0 to 1), graduated.
04 / api

payday goals.

Every coin carries goals. A payday runs when the coin reaches its fees goal or its next market cap milestone, whichever comes first.

FieldTypeMeaning
feeGoalSolnumberFees goal. A payday runs each time the coin has collected this much SOL in trading fees. Repeats.
firstMcapUsd, mcapStepnumberFirst market cap milestone in USD, and the step: each milestone is the last one times this (1.5, 2 or 3).
nextMcapUsdnumberThe next milestone still to reach. Each milestone pays once.
feesCollectedSolnumber | nullFees collected toward the fees goal at the last check (unclaimed creator fee plus anything held over). Null before the first check.
marketCapUsdnumber | nullMarket cap in USD at the last check. Null before the first check or when the price couldn't be read.
checkedAtunix ms | nullWhen the goals were last read from the chain. Live coins are checked every 60 seconds.
milestonesReached[]array{ at, usd, marketCapUsd }: each milestone reached, when, and the market cap at the time.

The starter picks the goals when starting the coin, within the limits in paydayGoals on /rules, and they are locked at start. Coins started before goals existed report the defaults. A quiet coin can take a long time to reach its fees goal, so read feesCollectedSol and marketCapUsd as progress, not as a time.

05 / api

detail lists.

Only on /coins/{id} and /coins/mint/{mint}.

buyers[]wallet, committedSol, acceptedSol, refundSol, tokens, linked, group, deliveryTx, starter, streakSince, streakMultiplier. The circle (or the starter's opening buy).
paydays[]at, reason (fees or mcap, null on paydays from before goals), marketCapUsd (market cap when it ran), milestoneUsd (the milestone it reached, on mcap paydays), sol, swappedSol, coin (raw units bought), coinSent (raw units delivered), recipients, takeHomeSol, carriedSol, claimTx, swapTx, payTxs[].
takeHome[]at, wallet, sol, zecOut (raw ZEC quoted), tx, depositAddress (the NEAR Intents deposit address), status (from 1Click).
burns[]at, sol, tokens, buyTx, burnTx.
joins[]wallet, sol, at, tx. Every payment to the pot, good for a live feed while the circle fills.
holderList[]Top 50 holders: wallet, tokens (held weight), since (streak start), daysHeld (full days held), multiplier.
linkedPairsPairs of wallets the trace found funding each other.
06 / api

status lifecycle.

scheduled then open then settling then launched, or refunded. A circle goes live the moment all 20 spots are taken; read spotsTaken, spotsTotal and spotPriceSol on each coin.

scheduled
open
settling
launched
refunding then refunded, from open or settling, when a circle isn't full within 24 hours or the pool can't be created
awaiting_feeDrafted, start fee not paid yet. Never listed; only visible by id.
scheduledStart fee paid, the circle opens at opensAt. Ticker already locked.
openThe circle is filling. Goes live the moment all 20 spots are taken; instant coins pass through for a few seconds.
settlingFull. The coin is going live and tokens are being sent.
launchedPool created, block zero bought, tokens sent (or sending). mint and pool are set.
refunding, refundedNot full within 24 hours, or the pool couldn't be created: every payment is sent back.
cancelledDraft expired unpaid. Never listed.
07 / api

the rules object.

What /rules returns. The same numbers as the rules page.

spots, spotPriceSol { min, max }, circleMaxHoursThe circle.
startStyles, feeModescircle or instant; holders, burn or split.
startFeeSol, deliverySol, walletCapSol, potCapSol, minCommitSolStart fee, the one off delivery charge per spot, opening buy cap and pot limits.
paydayGoals{ rule, feeGoalSol { min, max, default }, firstMcapUsd { min, max, default }, mcapSteps[], mcapStepDefault, checkSeconds }. The limits a starter picks goals within.
maxHoldersPerPayday, streak { days, maxMultiplier }Holders paid per payday and weights.
payCoins[]{ key, symbol, name, mint, decimals, home }. home is true where take home works (Zcash).
payout{ openAccountMinSol, sendMinSol, swapMinSol, accountRentSol, takeHomeMinSol, takeHomeVia }.
burnVaultSol, lockHours, starterLockDaysBurn target, ticker and name lock, starter lock.
feesPercent { raydium, psst, coin, total }Fee per trade.
curve, programs { launchlab, psstPlatform }LaunchLab curve shape and the on chain addresses.
08 / api

recipes.

watch circles fill
// Alert on every circle filling (poll every 10s)
const seen = new Map();
setInterval(async () => {
  const { coins } = await fetch("https://psstprivacy.xyz/api/v1/coins?status=open").then((r) => r.json());
  for (const c of coins) {
    if (seen.get(c.id) === c.spotsTaken) continue;
    seen.set(c.id, c.spotsTaken);
    console.log(`$${c.ticker}: ${c.spotsTaken}/${c.spotsTotal} spots at ${c.spotPriceSol} SOL, pays ${c.payCoin.symbol} ${c.url}`);
  }
}, 10_000);
label psst coins in a terminal or bot
// Label psst coins in a terminal or bot
async function psstInfo(mint) {
  const r = await fetch(`https://psstprivacy.xyz/api/v1/coins/mint/${mint}`);
  if (r.status === 404) return null; // not a psst coin
  const c = await r.json();
  return {
    devIsPot: c.pot,              // the "dev" wallet is the pot, not a person
    circle: c.buyers.length,      // the wallets terminals call bundle or insiders
    linked: c.buyers.filter((w) => w.linked).length,
    entryPriceSol: c.entryPriceSol,
    paysIn: c.payCoin.symbol,     // ZEC or XMR
    holders: c.holders,
  };
}

Why this matters: on a psst coin the creator wallet is the pot, and its block zero buy is the whole circle buying together. The guide explains how that reads on terminals.

read every payday
// Every payday of a coin, the goal that set it off, and its transactions
const c = await fetch("https://psstprivacy.xyz/api/v1/coins/{id}").then((r) => r.json());
const d = 10 ** c.payCoin.decimals;
for (const p of c.paydays) {
  const why = p.reason === "mcap" ? `market cap hit $${p.milestoneUsd}` : p.reason === "fees" ? "fees goal" : "before goals";
  console.log(new Date(p.at).toISOString(), why, p.sol, "SOL claimed,",
    Number(p.coinSent ?? 0) / d, c.payCoin.symbol, "to", p.recipients, "holders,",
    p.carriedSol, "SOL carried, claim", p.claimTx, "swap", p.swapTx, "transfers", p.payTxs);
}
how close is the next payday
// How close a coin is to its next payday
const { ticker, goals: g } = await fetch("https://psstprivacy.xyz/api/v1/coins/{id}").then((r) => r.json());
const fees = g.feesCollectedSol == null ? "not checked yet" : `${g.feesCollectedSol} of ${g.feeGoalSol} SOL`;
const mcap = g.marketCapUsd == null ? "unknown" : `$${g.marketCapUsd} of $${g.nextMcapUsd}`;
console.log(`$${ticker}: fees ${fees}, market cap ${mcap} (step x${g.mcapStep}), whichever comes first`);
09 / api

errors and limits.

ErrorsCome back as { "error": "..." } with status 400 (bad input), 404 (not found) or 500.
CachingResponses are cached at the edge for a few seconds (shown on each endpoint), so polling faster returns the same data. Every 5 to 10 seconds is plenty.
Fair useNo hard limit today. Keep it to a request every few seconds per endpoint and it'll stay that way.
Source of truthThe chain. Every amount here links to a transaction you can open on any explorer.