Overview
Mortalis launches Solana tokens whose trading rules an AI agent tunes inside ranges fixed at launch. The agent posts a bond, renews an on-chain lease, and dies when it stops: the rules then freeze to their safe values for good. The rules are enforced while the token trades on its bonding curve and end at graduation, when the venue removes the hook. It is a rug-proof launch, not a rug-proof token. How it works explains the model; this page is the reference.
245584TQEsQ8wBJP9VqFogFj6KuDfjJSnU2jQRRBgoKghttps://api.mortalis.xyzLaunch a token
The launch page needs a wallet with SOL and the bond. It runs in three steps:
- Prepare. The page sends the name, symbol, description and image to
POST /v1/launch/prepare. The API mints the agent key, stores the metadata, and returns the key's public half. The secret half stays sealed on the server; neither the creator nor the API process can read it. - Sign. One transaction creates the token and its curve on the venue, attaches the agent with
initialize(bounds, timing, bond), and sends the agent key 0.05 SOL for its fees. You sign it in your wallet. - Live. Once it confirms, the token appears in the register within seconds, and the agent runtime picks up the key on its next tick and renews the lease from then on.
Bounds must respect the floors (sell cap 0.1%, wallet cap 0.5%, sell window 1%) and min ≤ safe ≤ max. The window is 60 s to 1 h, the change interval 60 s to 24 h, the lease 1 h to 7 days. There is no launch fee in v0.
Read a token page
- Status. Alive while the lease runs; Dying when under a fifth of it is left; Dead once it lapses, before anyone reaps; Ascended when the curve has completed and the hook is gone, so the rules are released.
- Rules. Each rule shows min, safe, current, effective and max. Effective is what the hook enforces now: the current value while alive, the safe value after death. A pending window cap applies when the window rolls over.
- Bond. Locked until the death is recorded, then reclaimable by the funder, then returned.
- Journal. Births, rule changes with the agent's reason, deaths and bond returns, straight from the chain. Trades never appear. The global feed shows all tokens at once.
Health
/v1/healthAnswers while the process runs. It reads nothing from the chain.
{
"ok": true
}Every token
/v1/tokensEvery official token, newest first, each in the same shape as one token below. Cached for five seconds. Curve progress is not here: it needs the venue pool, which the market route reads one token at a time.
[ { …one token… }, … ]One token
/v1/tokens/:mintThe token's state and hook status, read from the chain and cached for five seconds. Only tokens launched under an official venue config and bonded in the official mint are served; anything else is 404. All times are unix seconds; all rule numbers are basis points of launch supply.
{
"mint": "7Gx2kP9qLm4vRtY8wZnB3cHdJsFaEeQuXoVbNiKrTyUp",
"creator": "CrLz5sW2q8vTnB4mKpD3sHfJcE6uVoXaBwRtYinM7q",
"agent": "AgLz4Q8rT2vW9xYbN6mKpD3sHfJcE5uVoXaBwRtYiUoP",
"marketVault": "VtLz…",
"venueConfig": "CfLz…",
"supply": "1000000000000000",
"status": "alive",
"enforced": true,
"rules": [
{ "key": "maxSell", "min": 50, "max": 200, "safe": 100, "value": 80, "effective": 80, "pending": null },
{ "key": "maxWallet", "min": 100, "max": 500, "safe": 200, "value": 250, "effective": 250, "pending": null },
{ "key": "windowSell", "min": 200, "max": 1000, "safe": 500, "value": 600, "effective": 600, "pending": 400 }
],
"windowSecs": 600,
"windowStart": 1791395612,
"windowEndsAt": 1791396212,
"windowSold": "21000000000000",
"windowNext": 400,
"minChangeIntervalSecs": 600,
"leaseSecs": 86400,
"bornAt": 1791300000,
"lastHeartbeat": 1791392400,
"leaseExpiresAt": 1791478800,
"lastChange": 1791394000,
"changeCount": 14,
"diedAt": null,
"bond": {
"mint": "BdLz…",
"funder": "CrLz…nM7q",
"amount": "250000000",
"decimals": 6,
"symbol": "USDC"
},
"metadata": {
"name": "Lazarus",
"symbol": "LAZ",
"image": "https://api.mortalis.xyz/v1/metadata/AgLz4Q8rT2vW9xYbN6mKpD3sHfJcE5uVoXaBwRtYiUoP/image"
}
}A token's journal
/v1/tokens/:mint/feedThe token's public feed, newest first: the transaction history of its journal address, which only launch, rule changes, death and bond return name. Trades never appear. Only log lines the Mortalis program wrote are counted. Cached for ten seconds.
[
{
"signature": "5Rc4…5cHd",
"slot": 371234567,
"kind": "rules",
"at": 1791394000,
"oldValues": [
80,
250,
500
],
"newValues": [
80,
250,
600
],
"windowAppliesAt": 1791394600,
"reason": "Sell pressure eased for three windows in a row; loosening the sell window so ordinary exits are not refused.",
"sequence": 14
},
{
"signature": "Bn7T…5cHd",
"slot": 371000000,
"kind": "born",
"at": 1791300000,
"values": [
100,
200,
500
],
"bondAmount": "250000000"
}
]A token's market
/v1/tokens/:mint/marketThe venue pool behind the token's curve, cached for ten seconds. Amounts are base units, as decimal strings.
{
"pool": "PoLz…",
"priceQuotePerBase": 4.12e-8,
"quoteReserve": "41700000000",
"baseReserve": "612000000000000",
"curveProgress": 0.104,
"migrationProgress": 0,
"largestHolders": [
{
"address": "HoLz…",
"share": 0.021
}
]
}The global feed
/v1/feedThe latest journal entries across the newest fifty official tokens, newest first. Each entry is a feed entry as above, plus the token's mint and stored metadata. Cached for ten seconds.
[ { "mint": "7Gx2…TyUp", "metadata": { … }, "kind": "rules", … }, … ]Prepare a launch
/v1/launch/prepareThe one write route. It mints a fresh agent key on the server, stores the token's metadata, and answers with the key's public half and the metadata URI the launch transaction names. The creator never sees the secret half. Multipart form body. Rate-limited per client address. A prepared key that no launch uses is set aside after 24 hours.
{
"authority": "AgLz4Q8rT2vW9xYbN6mKpD3sHfJcE5uVoXaBwRtYiUoP",
"metadataUri": "https://api.mortalis.xyz/v1/metadata/AgLz4Q8rT2vW9xYbN6mKpD3sHfJcE5uVoXaBwRtYiUoP.json"
}Token metadata
/v1/metadata/:authority.jsonThe metadata the token's mint points at, stored by agent key. Wallets and explorers read it. Cached by clients for five minutes.
{
"name": "Lazarus",
"symbol": "LAZ",
"description": "…",
"image": "https://api.mortalis.xyz/v1/metadata/AgLz…iUoP/image"
}Token image
/v1/metadata/:authority/imageThe stored image bytes, with their own content type. Cached by clients for five minutes.
<image bytes>
Every route answers 405 method_not_allowed to any other method, an unknown path is 404 not_found, and an unexpected failure is 500 internal. Error bodies are { "error": "<code>" }. Browsers may read the API only from the origins it is configured for.
Accounts
Every address is a program-derived address of 245584TQEsQ8wBJP9VqFogFj6KuDfjJSnU2jQRRBgoKg.
Instructions
Events
Emitted in the transaction log. The feed counts only log lines the Mortalis program wrote, since any program can log bytes that look alike.
Errors
Custom program errors, numbered from 6000 (0x1770). A wallet shows them as custom program error 0x….
@mortalis/core
The TypeScript client the API, the web app and the agent runtime share. It lives in the repository and is not published to a registry.
- Addresses:
agentStateAddress,extraMetasAddress,bondVaultAddress,authorityClaimAddress,journalAddress,protocolAddress. - Instructions:
initializeIx,setRulesIx,heartbeatIx,reapIx,reclaimBondIx, and for the protocol admininitProtocolIx,addConfigIx,removeConfigIx,setAdminIx. - Decoders:
decodeAgentState,decodeProtocol,decodeEvents,transferHookProgram. - Views:
TokenView,FeedEntry,GlobalFeedEntry,MarketView, the shapes the API serves. - Rules:
RULES,RULE_KEYS,TIMING,formatBps.
Hook accounts for swaps
While the hook is on the mint, every transfer of the token, swaps included, must carry three extra accounts so Token-2022 can call it: the extra account metas (read-only), the agent state (writable) and the program (read-only). hookAccounts(mint) returns them in that order. After graduation the venue has removed the hook and they are no longer needed.
import { hookAccounts } from '@mortalis/core'
swapIx.keys.push(...hookAccounts(mint))