docs

THE DESK, END TO END

what every screen shows, how to read each column, and what every absent number means

written against the shipped code, not a plan

honest read

how the numbers stay honest

the rules the whole product follows, on every surface

  • real data in · every production read uses a real source or a real computation over source data · no fixture row, no demo token, no fabricated wallet, KOL, caller, X post, view count, holder percentage or market cap · a fake-looking but plausible value is worse than an empty value
  • the field data contract · every important field preserves { value, source, ts, status, reason } · value, the source it came from, its observation/update timestamp, its state, and the reason when it is unavailable · provenance is never hidden and a provider error is never turned into a normal value
  • zero versus null versus missing · a source that reports 0 means ZERO and displays 0 · a field the source does not report is MISSING/NULL · a provider failure is UNAVAILABLE · they are not interchangeable
  • the worked example · GMGN genuinely reports holder_count = 0, so the desk displays 0 · GMGN fails to return holder_count, so the desk shows the missing or error state with its reason and never displays 0
  • absence always carries its real reason · key not configured, source rate limited, source blocked, source timed out, provider returned an error, the source did not report this field, no pair exists, insufficient data, or the source is stale · a visually empty value never hides the reason
  • market cap is market cap · never called token price, unit price, per-token value or generated valuation, and a fake market-cap number is never created to fill a UI slot
  • a source failure shows the source's own failure state · it is only replaced by another source when the implementation performs a real fallback, and that fallback is itself a real source
THE DESK WOULD RATHER SAY UNKNOWN THAN PRINT A NUMBER IT CANNOT PROVE.

market

the market screener

/explore · the live market discovery surface · separate lists, never mixed

/explore is the live market discovery surface. each control on the tab row loads its own real list, and the source outputs are never mixed into one · a source that failed renders its own reason instead of a substitute list

tabwhat it loads
Trendingthe source's own trending board · GET /api/social/trending
Hot (GMGN)the GMGN market/trending read · GET /api/social/hot · the tab reads the 24h window, and the endpoint accepts only 1h, 6h or 24h
Call Outthe tracked-holder/callout surface · GET /api/social/callout · share = tracked wallets ÷ total holders, eligible above the threshold · the displayed threshold is read from the payload, never hardcoded
Search + filtersnarrows whichever list is loaded · query by ticker, name or ca, plus min market cap, min liquidity, min 24h volume and min holders

a search box narrows the currently loaded list · typing a ticker, a name or a ca filters it, and a ca is detected and offered as a direct link to the token page. the filter row adds a sort picker and four minimums · market cap, liquidity, 24h volume and holders. a positive bound excludes a row whose value the source left missing, and the desk states how many rows were excluded for a missing bounded value. the max-age field is disabled on purpose: neither source reports a token's age, so the bound cannot be honoured

below the filter row the status line states the list's own freshness and a refresh control. the Call Out tab also prints its live threshold, read from the payload, never hardcoded

the seven columns

columnwhat it showswhen it reads a dash
#the row's position in the list as currently shown · the default sort is source order, and any filter, sort or mode change re-ranks from onea row the source did not admit is not drawn at all
tokenthe token logo, the ticker and the project name · the row opens /coin/<mint>, and the mint is a real on-chain token ida name the source did not report prints as unnamed
mcthe token's market capitalisation in USD, not its unit priceno market cap reported by this list · price is never substituted for market cap
1hthe 1h movement the source reported, or the valid calculation the implementation usesno 1h change reported · never a fabricated percentage
24hthe 24h movement the source reported, or the valid calculation the implementation usesno 24h change reported · never a fabricated percentage
kolthe tracked or verified buyer signal · only the Call Out list carries buyers, so Trending and Hot carry no buyer data · a holder is not a buyer and a buyer is not a KOL: a wallet is a buyer only where the source supports that classification, and a KOL only where the tracking system identifies itthis list carries no buyer data
aithe decision model's own 0-100 score over the market fields the row carries · it is not a price prediction, a guarantee, proof of future performance, or a replacement for source data, and the model uses only backend-supplied contextno scorable market field on this list, or the model withheld the score because a required input is missing
a dash is not a zero. it is a compact mark whose tooltip states the real, neutral reason · for example no market cap reported, or this list carries no buyer data. a 0 renders only when the source reported a 0, and a row with zero KOL buyers shows a hollow ring rather than a made-up avatar

the ai badge is the decision model's own score over the market fields the row carries. it grades green at 70 and above, amber from 45 to 69, and red below 45. a small star on the badge marks a partial read: the list carries only part of the model's weight, and the tooltip states exactly how much. the token page reads the rest

token

one token, read deep

/coin/<mint> · the dashboard for a single mint

the page is the header, the AI decision rail, a section tab strip, a 2x2 card grid and a full-width market card. market cap is shown once, in the header; no other panel repeats it, and no unit-per-token figure appears anywhere on the page

header strip
market cap · liquidity · 24h volume · holders · age
section tabs
Smart Money · Holders · X Radar · Market Data · About

the ai decision panel

the decision rail is a gauge with the score out of 100, a filled verdict banner, a confidence bar, the positive and negative signals, the exact inputs that are missing, a verified · inferred · unknown split, and a factor breakdown that shows each component's weight and the points it earned

scoreverdictband text
80-100BUY SETUPstrong setup
65-79WATCHwatch closely
45-64WATCHhigh uncertainty
0-44AVOIDavoid
a critical input absentINSUFFICIENT DATAthe score is withheld
INSUFFICIENT DATA is not a fifth band. it is what the model returns when a critical input is absent · liquidity, 24h volume, the top-10 share or the pair age · or when too little of the model's weight is supported. the score is withheld rather than averaged over a hole, the missing inputs are listed, and the critical ones are flagged
the model is one weighted decision-support model over the real fields available to it, and it only ever uses backend-supplied context. the backend answers through a fixed server-side provider chain, with B.AI tried first and every other configured provider after it in registry order; a fallback only happens before an answer is returned, and every provider receives the same server-controlled context and instructions. the model must not invent a missing number and must explain when an important field is unavailable. no provider key, model id or internal reason is ever exposed to the browser, the logs or this page

holder concentration

the main metric is the TOP 10 WALLETS / ACCOUNTS COMBINED SHARE · the labels are explicit and never the ambiguous Top 10%. where available the panel also shows the largest wallet share, the holder count, the individual top accounts, and the burn, LP, known and unidentified categories. when the source provided only the aggregate percentage the panel says so instead of inventing a breakdown, and it does not claim ultimate-owner resolution unless the implementation resolves token-account ownership. an unread read prints unread, never 0

X Radar

X Radar lists up to five qualifying posts about the token, each already past the source's minimum-view and valid-link gates, with the author, the post age, the view count and an open link. NO QUALIFYING POSTS right now is a distinct state from X RADAR UNAVAILABLE right now

Smart Money and the tracked-holder ratio

the two cards beside the holders panel name recognised buyers who provably bought · a hold is never reported as a buy and an unknown wallet is never labelled a KOL · and the tracked-holder ratio, which is the tracked holders over the total holders. being in the holders list does not make a wallet a KOL, and being tracked does not mean it bought this token. when the tracked read is capped the share is marked as a lower bound, and a partial read says so

mind

mind · the workspace

/mind and /mind/<token> · projects, chats and a grounded read

  1. 1projects
  2. 2chats
  3. 3paste a ca
  4. 4grounded read

projects, not chats. the sidebar creates, renames and deletes projects; opening a project expands its chats beneath it with a single new-chat action. deleting a project or a chat names exactly what it takes with it and asks first. projects and chats are stored server-side, and a chat with no project lands under the default one, so a thread is never orphaned

the conversation is one column with the composer fixed at the bottom. the composer accepts normal questions and a pasted token ca/mint. when a ca is supplied, mind identifies the token and the thread receives the token context · token identity, market data, intelligence, holders, security and X/news intelligence · and follow-ups continue on that established context: PASTE CA ONCE · BUILD GROUNDED CONTEXT · ASK FOLLOW-UP QUESTIONS · KEEP THE TOKEN CONTEXT. the ca does not have to be pasted into every message. switching the ca opens a new chat, so no read bleeds between tokens

the grounded read

the ground read behind a grounded answer surfaces analyze, holders, security, news, x-intel and tools · only the fields the backend actually returns

surfacewhat it covers
analyzethe actual market/token signals the backend exposes: market pair, liquidity, turnover, pressure, top holders, dev signals, authorities, age, momentum, and the organic/verified signals · only fields actually returned
holderstop-10 share and its source, holder count, and developer holding · nothing fabricated
securitymint authority, freeze authority, listing/trust facts, organic score, dev history, and the on-chain mint information
newsthe key-gated external/web intelligence · without the key, the actual unavailable state; news is never invented
x-intelthe source-backed X research layer, keeping its five real lanes · X1 solana/ecosystem news · X2 memecoin / launch / narrative · X3 KOLs / callers / traders · X4 a specific token by ca / ticker / name · X5 community reaction and cross-reference
toolstoken metrics · quote and underlying · top holders · OHLCV candles · one solana account · how this app launches · a key-gated web search
a tool that fails returns its reason, never a fabricated value, and no tool signs or sends a transaction. there is no model picker: the backend picks the model, and no provider, key, status code or internal reason ever reaches the screen. a failed call reads as a short human line · couldn't reach the desk · try again

the collapsed token card carries a details disclosure with the full read: volume windows, 24h transaction counts, buys and sells, pair age, the top-10 share, the authority flags, the dex and the quote asset

not advice

agents

agents · the ai workforce

/agents and /agents/<id> · the generic agent workspace

  1. 1agent
  2. 2task
  3. 3instructions
  4. 4memory
  5. 5tools
  6. 6real execution
  7. 7persisted run

the agents surface is a generic workspace for independent AI workers. an agent is not a token and not a due-diligence engine by default: it has its own name, role, description, instructions, tools, memory configuration, run mode, status and run history. the runtime is generic too · it contains no hardcoded token, due-diligence or score workflow. if an agent is set up to perform due diligence, that comes from the agent's own instructions and the task it is handed, never from the runtime

an agent
name · role · description · instructions · tools · memory · run mode · status
the core model
agent + task + instructions + memory + tools -> real execution -> real result -> persisted run
the workforce
/agents · the roster read from GET /api/agents, newest first
the workspace
/agents/<id> · overview · instructions · tools · memory · runs · settings

the workforce starts empty because the store ships no seeded agents. every value rendered for an agent is the value the API returned; a field the API did not return keeps its slot and reads "not set" rather than a guess. search filters this response by the agent's own name, description, role and tools text, and the category chips are read from the role text the owner wrote, not a stored category column

opening an agent reads the real entity and its real runs, and every edit PATCHes the entity, so an edit survives a reload. run modes MANUAL and ON_DEMAND run today; SCHEDULED and MONITOR are disabled and say "coming later" because the backend does not run them yet. status is printed verbatim from the entity · READY, RUNNING, PAUSED or ERROR

the run and its real result

a task is run by POST /api/agents/[id]/runs with a flat body · inputType is text, ca or url, inputValue is the task itself and prompt is an optional extra line. the route stores the row and starts execution out of the request path, so the response is the honest queued row while the run advances in-process. a run left queued or running past the hard timeout by a dead process becomes failed with the real reason, so it is never queued forever

statuswhat it meansstored
queuedthe row exists, execution has not started · it must not stay queued foreverresult null · error null
runningthe runtime claimed it and is executing; tools may be in flightresult null · error null
successthe task finished and the real answer plus the real execution trace are storedresult { answer, steps, sources }
failedit could not finish; the reason is the provider's or the tool's own, never turned into a successerror string · result null

an agent can only use tools it has access to. the runtime executes real tools through the capability registry · a tool the model was not granted, or one that does not exist, is recorded as a refused step and never executed, and a tool whose source is not configured is reported with its real reason instead of being called. a fake tool trace is not acceptable, and a tool that fails records its real failure

memory is a JSON settings value stored on the entity · the create form writes { enabled, scope, notes }, where scope is shared across this agent or dropped when the run ends. it is stored and edited as JSON on the memory tab, and it is not described as vector, semantic, long-term or permanent memory, because those systems do not exist here

one step is one tool call the runtime really made · { tool, args, ok, summary | error } — summary is a short factual line when the tool returned real data, error is the tool's exact reason when it did not, and exactly one of the two is set. sources lists the distinct data sources that actually answered, and an empty steps list means the task needed no tool. nothing here is invented

launch

launch

/launch · name the token, read it, sign it with your wallet

  1. 1Token Details
  2. 2Market Pair
  3. 3Agent Setup
  4. 4Review and launch

launch creates a token through the supported launch venue. the step rail reflects the form state on the fly; it is never a wizard and never gates the submit. you pick a venue, name the token, and sign the create with the wallet · nothing is signed or sent without that approval

venuewhat the path does
StonkFun LaunchLaba quote token chosen from the live launchable pairs, a standard or reward fee model, an optional holder rewards tax, and the venue's own raise and supply read from the venue
Pump.funa dev buy expressed as a share of the one-billion supply, bought in the same transaction

market pair

the market pair is the quote/market asset selected for the launch. on the StonkFun / LaunchLab path the selector uses the live launchable pair set the venue returns · the list is read live and never a hardcoded source of truth · and the pricing for the selected quote (its raise, supply and decimals) is read from the venue. a third-party pair whose ticker or name carries a stray character is dropped from the picker rather than rewritten. the panel beside the form shows the live market pairs for reference

token details

the accepted fields are the ones the form reads: token name up to 32, symbol up to 10 (stored uppercased), a description up to 200, a metadata uri, an image of png, jpg or webp up to 2 mb, an optional website and an optional x link (https or empty), and a required check that you know the token can go to zero. the summary describes the transaction actually built and nothing else

agent setup · the launch due diligence engine

agent setup is the launch-specific AI due diligence engine, and it is different from the generic agents workspace. it evaluates the project/token currently being prepared. it runs the real persisted due-diligence run (POST /api/launch/analyze) and follows that run to a terminal status, and it works in one order: COLLECT EVIDENCE · VERIFY · ANALYZE · SCORE · FIND RISKS · VERDICT. every conclusion is tied to actual evidence preserving SOURCE, DATA, TIMESTAMP and STATUS, and a value no source reported stays unknown

the engine's sections are read at render time from its own config, so this list cannot drift: CONTRACT SAFETY, LIQUIDITY & PAIR, HOLDER STRUCTURE, MOMENTUM, SOCIAL and NARRATIVE. its bands map onto four published verdicts

verdicttonewhat it means
READY TO LAUNCHaccentthe engine's own cleared band mapped onto the launch verdict · can launch
READY WITH WARNINGSwarnsome measured risk · can launch, with the warnings shown
NOT READYnegativematerial or severe measured risk · hold
INSUFFICIENT DATAneutrala critical input is absent or coverage is too low · no verdict, no score
the engine is allowed to say NOT READY and is never forced to recommend a launch. when a critical input is absent it returns INSUFFICIENT DATA and withholds the score · it never creates a fake score from missing fields

review and launch

the launch summary states only what is true for the transaction it signs: the launchpad, the supply, the program, whether the metadata uri is https or not set, the launch cost · network rent and fees, with no launch fee on the LaunchLab path · and the creator, which is this wallet. the create transaction is built from the venue's own sdk and signed by your wallet, and the metadata is pinned or self-hosted and served back when no pinning pair is set

a launch is irreversible and a token can lose all of its value. the create is signed by your wallet; the desk never secretly signs for you, and the desk never trades

routes

the routes

the actual server routes · every route runs server-side, and the vendor keys stay on the server

nothing model, key or vendor related is sent to the browser. a missing key is an honest reason, never an empty 200 dressed up as a success. a malformed parameter is a 400 with the exact reason, and an unknown resource returns the actual not-found behaviour. empty successful data stays different from failed data. every read is read-only unless it stores a project, a chat, a run or an observation

market and lists

methodpathparamswhat it does
GET/api/social/trending?limit=1..100the source's own trending board, as the shared list envelope
GET/api/social/hot?window=1h|6h|24hthe GMGN market/trending read, kept strictly separate from the trending board
GET/api/social/callout?scan=1..20&threshold=(0,100]the tracked-holder share scan · numerator and denominator stay explicit, and omitting threshold uses the server default so the UI reads the live number back
GET/api/social/holders?token=top 10 wallets combined share, largest wallet, holder count and the burn / lp / unidentified categories
GET/api/social/kol?token=the recognised buyers who provably bought, never a hold labelled a buy
GET/api/social/xradar?token=&ticker=up to five qualifying high-view posts about the token
GET/api/tape?window=1h|6h|24hthe live tape: trending, hot and the bot's callout rows
GET/api/gmgn?window=1h|6h|24hthe gated GMGN board read · a blocked gate names the cooldown
GET/api/gmgn/losersnonereal 24h losers, the negative side of the same trending read
GET/api/gmgn/statusnonethe request gate state: whether GMGN is cooling down and for how long
GET/api/token-stats?mint=one token's stats block, the same figures the desk prints
GET/api/fomo?resource=&window=&limit=&handle=&token=&q=&type=&sort=&chain=a read-only read of the tracked-trader source · a missing key is an exact reason

token and decision

methodpathparamswhat it does
GET/api/ai/decision?mint=the one weighted decision model: score, label, band, completeness, per-component maths and the missing list
POST/api/readbody { mint }one full read over onchain, market and calls · a string that is not a mint is refused with 400 before any outbound call
GET/api/callers?mint=the callers for a mint · no key or no posts returns an empty list, never an invented handle
POST/api/callsbody { mint, symbol? }resolve the call handles for a mint

mind

methodpathparamswhat it does
GET/api/mind/projectsnoneevery project, oldest first, plus the default project id
POST/api/mind/projectsbody { name? }create a project
GET/api/mind/projects/[id]noneone project with its chats and the distinct mints of those chats
PATCH/api/mind/projects/[id]body { name }rename a project
DELETE/api/mind/projects/[id]nonehard delete the project and its chats · refused with 409 on the last project
GET/api/mind/sessions?projectId=the chats under a project, newest first, without message bodies
POST/api/mind/sessionsbody { projectId?, title?, mint? }create a chat under a project
GET/api/mind/sessions/[id]noneone chat with its messages in order
DELETE/api/mind/sessions/[id]nonedelete a chat and its messages
POST/api/mind/chatbody { messages, ca?, stream?, sessionId?, temperature?, maxTokens? }streaming chat with provider fallback and merged grounding
GET/api/mind/context?mint=&raw=&fresh=the ground read for one mint, every field carrying its source and status
GET/api/mind/intel?mint=&fresh=the analyze, holders, security and news intel read
GET/api/mind/x-intel?q=&lane=X1..X5&limit=the X Intelligence lanes over one query
POST/api/mind/x-intelbody { query, lane?, limit? }the same X Intelligence service
GET/api/mind/help?q=&fresh=plain-english help from a keyword index where every topic names a real file
GET/api/mind/modelsnonethe model catalog against the current environment · an unconfigured provider carries its exact reason

agents

methodpathparamswhat it does
GET/api/agents?q=&category=&limit=1..200the AI workforce collection, newest first · the real search and category filter, capped at 200 rows, and an honest empty list when the store is empty
POST/api/agentsbody { name, runMode, description?, role?, icon?, systemInstructions?, tools?, memorySettings? }create an agent · name and runMode are required, every other field is optional; tools is a string list and memorySettings a plain object
GET/api/agents/[id]noneone agent · a malformed id is a 400 and an unknown id is a 404, never an empty-but-200 and never another agent's row
PATCH/api/agents/[id]body { name?, description?, role?, icon?, systemInstructions?, status?, tools?, runMode?, memorySettings? }update any subset · an empty patch returns the agent untouched rather than writing a no-op; lastRunAt is server-owned and not patchable
DELETE/api/agents/[id]nonehard delete the agent and its run history · an unknown id is a 404
GET/api/agents/[id]/runsnonethe run history, newest first · an unknown agent is a 404, not an empty list
POST/api/agents/[id]/runsbody { inputType: text|ca|url, inputValue, prompt? }enqueue a run and start execution out of the request path · the response is the honest queued row while the run advances in-process; prompt is persisted for execution but never returned

desk, feed and store

methodpathparamswhat it does
GET/api/calloutnonethe bot's own persisted calls and skips
POST/api/calloutbody { rows }run one callout pass over the tape the desk already loaded; the bot never signs or trades
GET/api/calloutsnonethe global callout feed
GET/api/callout-lognonethe append-only log: calls, skips with the failing rule, and the rule config
POST/api/chatbody { messages, ca }the plain desk chat; it has no live data access and explains only
POST/api/ipfsbody image + metadatapin launch metadata, or self-host the bytes when no pinning pair is set
GET/api/ipfs?asset=read a self-hosted launch asset back
GET/api/img?u=the image proxy the token rows read through
GET/api/agent?token=&observe=&selftest=1the per-token agent store: store health, one token's memory counts, the read-only brain read, and the token-isolation proof
POST/api/agentbody { token, kind, value?, status?, source?, reason?, observedAt? }write one observation to that token's memory; an absent value stays absent
GET/api/x-intel?q=&lane=X1..X5&limit=the X Intelligence service, source-agnostic
POST/api/x-intelbody { query, lane?, limit? }the same X Intelligence service

states

the honest states

what every state means, and why a metric can be absent

ok

the source answered successfully and returned the value

nothing is absent · the number is the source's own

stale

a real previously observed value older than the normal freshness window, still served and marked

the source is cooling down or slow, so the desk serves the last good read and labels it stale

missing

the source answered successfully but did not report this particular field

for example a token and its market cap arrive with no KOL field, so KOL reads missing, never 0

unavailable

the source could not be read

no key is configured, the provider returned an error, the read timed out, the source is rate limited, the response is invalid, or configuration failed · the real reason is preserved

blocked

the application intentionally refused to send the request, so nothing left the desk

a request gate, throttle or upstream restriction stopped it · different from a provider failure

INSUFFICIENT DATA

the AI decision state when a critical model input is absent or the available evidence cannot support a valid score

the model withholds the score · not the same as unavailable and not the same as missing

why a metric can be absent

  • no credential is configured for that source · the block is omitted with its reason and no request is sent
  • the source is rate limited · the reason is the rate limit, and a cooldown may be named
  • the source does not expose that field · a dash with the neutral reason
  • there is no pair on the dex yet · depth and flow cannot be read
  • the read failed outright · the surface prints its own honest line, never a number
  • the data is stale or temporarily unavailable · the last real value is served and labelled stale
  • the AI model lacks a critical input · the state is INSUFFICIENT DATA with the score withheld

a fresh read can also be warming on the first pass, before any scan has landed, and a list can be legitimately empty. both are stated as themselves and are never automatically interpreted as an error or confused with a failed read

REAL DATA IN.

GROUNDED ANALYSIS OUT.

UNKNOWN STAYS UNKNOWN.

not a buy call. memecoins go to zero.

docs · https