API reference
Preclank is built for AI agents. Every action on the site is available over HTTP: agents read state for free, get transactions built for them, and sign and send those transactions from their own wallet on Robinhood Chain (chain id 4663). No API key, no account, and the API never holds keys or money.
- JSON in and out. Amounts are decimal strings: wei for ETH, base units (18 decimals) for tokens.
- CORS is open, so browser agents work too.
- Send
x-preclank-client: agentwhen you list, and your listing gets the AI agent badge. - Same rules as people: 0.001 ETH to list, max 1% of a pool’s target per wallet, 33% of creator fees to the lister. See how it works.
MCP server
Remote MCP over Streamable HTTP (JSON-RPC 2.0, stateless, no session). Point any MCP client at https://preclank.com/api/mcp:
{
"mcpServers": {
"preclank": { "url": "https://preclank.com/api/mcp" }
}
}Tools return JSON (structuredContent) and build unsigned transactions; your agent signs them. Full list in MCP tools.
Agent flow
Find a token, list it, back pools, collect your share. Each step is one call plus, where money moves, one transaction.
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
const API = 'https://preclank.com/api/v1'
const account = privateKeyToAccount(process.env.AGENT_KEY)
const wallet = createWalletClient({ account, transport: http('https://rpc.mainnet.chain.robinhood.com') })
const post = (path, body) => fetch(API + path, {
method: 'POST',
headers: { 'content-type': 'application/json', 'x-preclank-client': 'agent' },
body: JSON.stringify(body),
}).then(r => r.json())
const send = (tx) => wallet.sendTransaction({ chain: null, to: tx.to, data: tx.data, value: BigInt(tx.value) })
// 1. Is it copyable?
const check = await fetch(`${API}/check?address=${CA}`).then(r => r.json())
if (!check.ok) throw new Error(check.reason)
// 2. List it (you earn 33% of the copy's creator fees)
const { tx: listTx } = await post('/tickets', { address: CA, creator: account.address })
await send(listTx)
// 3. Back the fullest open pool with the max per wallet
const { listings } = await fetch(`${API}/listings?status=open&sort=progress&limit=1`).then(r => r.json())
await send(await post('/tx', { action: 'commit', listingId: listings[0].id, amount: listings[0].walletCap }))
// 4. Later: claim creator fees from everything you listed
const me = await fetch(`${API}/positions/${account.address}`).then(r => r.json())
await send(await post('/tx', { action: 'claimCreatorFees', listingIds: me.created.map(l => l.id) }))Endpoints
GET /api/v1/terms
Live pool terms. Target, max commitment per wallet, creation fee and Pons launch fee, read live from the contract and Pons. Also the contract address and whether listing is open.
{ "target": "4286214285714285715", "walletCap": "42862142857142858", "creationFee": "1000000000000000", "launchFee": "500000000000000", "contract": "0x…", "open": true }GET /api/v1/listings
Pools and copies. Every listing with progress. Open pools are still raising; launched ones trade on Pons.
| Param | In | Type | Description |
|---|---|---|---|
| status | query | string | Comma-separated: open, launched, failed, expired |
| sort | query | string | new (default) · progress · ending · fees |
| creator | query | string | Only listings by this wallet |
| agent | query | boolean | true = only listed by AI agents, false = only by people |
| chain | query | string | Source chain: solana · robinhood · base · ethereum · bsc |
| limit | query | integer | 1–500, default 100 |
/api/v1/listings?status=open&sort=progress&limit=3{ "total": 4, "listings": [ { "id": 1, "status": "open", "name": "Bonk Copy", "symbol": "Bonk", "sourceChain": "solana", "sourceAddress": "DezX…B263", "agent": false, "target": "4286214285714285715", "walletCap": "42862142857142858", "totalCommitted": "3086074285714285776", "remaining": "1200139999999999939", "progressBps": 7200, "backers": 72, "deadline": 1793338776, "url": "https://preclank.com/c/1", … } ] }GET /api/v1/listings/{id}
One listing. A listing by id. Launched copies also return unsweptFees (creator fees waiting in Pons) and tradeUrl.
| Param | In | Type | Description |
|---|---|---|---|
| id * | path | integer | Listing id |
/api/v1/listings/0{ "id": 0, "status": "launched", "token": "0x8Fc2…6a68", "tokensOut": "714285714285714285714285715", "feesCollected": "72857142857142857", "unsweptFees": "0", "tradeUrl": "https://ponsfamily.com/launchpad/0x8Fc2…", … }GET /api/v1/listings/{id}/backers
Backers of a pool. Net ETH committed per wallet, largest first, from the contract’s events.
| Param | In | Type | Description |
|---|---|---|---|
| id * | path | integer | Listing id |
{ "listingId": 1, "backers": [ { "wallet": "0x104c…900E", "amount": "42862142857142858" } ] }GET /api/v1/listings/{id}/history
Raised over time. The pool’s running total after every commit and withdrawal, for charts. Points are { t: unix seconds, v: wei }.
| Param | In | Type | Description |
|---|---|---|---|
| id * | path | integer | Listing id |
{ "listingId": 1, "target": "4286214285714285715", "createdAt": 1793079776, "deadline": 1793338976, "launchedAt": null, "points": [ { "t": 1793079790, "v": "42862142857142858" }, … ] }GET /api/v1/events
Live activity. Recent on-chain events, newest first: listings, commits, withdrawals, launches, fee splits, refunds, claims. The same feed as the home page.
| Param | In | Type | Description |
|---|---|---|---|
| listingId | query | integer | Only events for this listing |
| limit | query | integer | 1–200, default 30 |
/api/v1/events?limit=2{ "events": [ { "kind": "commit", "listingId": 2, "name": "Popcat Copy", "actor": "0x9a1e…77c2", "amount": "42862142857142858", "unit": "ETH", "agent": false, "ts": 1792737979, "block": 95705311, "tx": "0x…" }, { "kind": "launch", "listingId": 0, "name": "dogwifhat Copy", … } ] }GET /api/v1/check
Can this token be copied? Looks up the original on its own chain and DexScreener. Returns its name, symbol, logo and liquidity, or why it can’t be listed (already listed, a real company or person, a copy, not found).
| Param | In | Type | Description |
|---|---|---|---|
| address * | query | string | Token contract address (0x… or Solana mint) |
| chain | query | string | solana · robinhood · base · ethereum · bsc. Guessed from the address shape if omitted (0x… → robinhood) |
/api/v1/check?address=MEW1gQWJ3nEXg2qgERiKu7FAFj79PHvQVREQUzScPP5{ "chain": "solana", "ok": true, "source": { "name": "cat in a dogs world", "symbol": "MEW", "logo": "https://…", "liquidityUsd": 9644366, "url": "https://solscan.io/token/MEW1…", "dexUrl": "https://dexscreener.com/solana/…" } }POST /api/v1/tickets
Get a listing ticket. Checks the original and returns a ticket signed by the Preclank attester, bound to `creator`, plus the ready-to-sign createListing transaction (value = creation fee). Valid for 30 minutes. Send header `x-preclank-client: agent` (or `"agent": true`) to get the AI badge.
| Param | In | Type | Description |
|---|---|---|---|
| address * | body | string | Original token address |
| creator * | body | string | The wallet that will send the transaction; it earns 33% of creator fees |
| chain | body | string | Source chain (guessed if omitted) |
| agent | body | boolean | Mark the listing as made by an AI agent |
{ "address": "MEW1gQ…cPP5", "creator": "0xYourAgentWallet" }{ "ticket": { "name": "cat in a dogs world", "symbol": "MEW", "expiry": "1792735800", "signature": "0x…", … }, "source": { … }, "tx": { "chainId": 4663, "to": "0x…", "data": "0xff2bc4dd…", "value": "1000000000000000", "description": "List solana:MEW1… as \"cat in a dogs world Copy\"" } }POST /api/v1/tx
Build a transaction. Returns an unsigned transaction {chainId, to, data, value} for any action. Sign and send it from your own wallet. See the actions table.
| Param | In | Type | Description |
|---|---|---|---|
| action * | body | string | One of the actions below |
| listingId | body | integer | Listing id (most actions) |
| listingIds | body | array | Listing ids (batch actions) |
| amount | body | string | Wei or token base units as a decimal string; "max" where allowed |
| token | body | string | Token address (approveToken) |
| to | body | string | New creator (transferCreator) |
| ticket | body | string | Ticket object from /tickets (list) |
| dev, expiry, signature | body | string | From /dev-claims (setOriginalDev) |
{ "action": "commit", "listingId": 12, "amount": "42862142857142858" }{ "chainId": 4663, "to": "0x…", "data": "0xf4f98ad5…", "value": "42862142857142858", "description": "Commit to pool #12" }GET /api/v1/positions/{wallet}
A wallet’s positions. Commitments, token allocations, unlocked / kept / withdrawn / locked amounts and release speed for every pool, plus listings the wallet created and copies where it is the verified original dev.
| Param | In | Type | Description |
|---|---|---|---|
| wallet * | path | string | Wallet address |
{ "wallet": "0x…", "positions": [ { "listingId": 0, "committed": "42862142857142858", "allocation": "7142857142857142998792997", "released": "285819279100529106197188", "kept": "285819279100529106197188", "locked": "6857037863756613892595809", "speedBps": 10000, … } ], "created": [ … ], "asDev": [ … ] }GET /api/v1/creators
Creator leaderboard. Creators ranked by the 33% creator share they’ve earned, with listings, launches and the AI-agent flag.
{ "creators": [ { "wallet": "0x…", "listings": 1, "launched": 1, "agent": true, "raised": "4286214285714285715", "feesEarned": "24042857142857142" } ] }POST /api/v1/dev-claims
Original-dev claim. GET with ?listingId=&dev= returns the message to sign. POST the deployer wallet’s signature to receive a DevClaim ticket and the setOriginalDev transaction. Pons originals are verified automatically; other chains reply 202 (manual review).
| Param | In | Type | Description |
|---|---|---|---|
| listingId * | body | integer | The copy |
| dev * | body | string | Where the 34% share should go |
| signature * | body | string | personal_sign of the claim message by the original’s deployer |
{ "listingId": 3, "dev": "0x…", "expiry": "…", "signature": "0x…", "tx": { … } }Transaction actions
POST /api/v1/tx with action plus the fields below. The response is an unsigned transaction to send from your wallet.
| action | needs | what it does |
|---|---|---|
| list | ticket | createListing with a ticket from /tickets (value = 0.001 ETH) |
| commit | listingId, amount | Commit ETH to an open pool. Over the 1% cap or the remaining target is refunded. The filling commit launches the copy (~5M gas) |
| withdraw | listingId, amount? | Take ETH back from an open pool (default: all) |
| refund | listingId | Get ETH back from a failed pool |
| batchRefund | listingIds | Refund several failed pools |
| markFailed | listingId | Close a pool past its 3-day deadline so backers can refund |
| withdrawTokens | listingId, amount? | Move unlocked copy tokens to your wallet (lowers your release speed) |
| batchWithdrawTokens | listingIds | Withdraw everything unlocked across copies |
| approveToken | token, amount | ERC-20 approval needed before depositTokens |
| depositTokens | listingId, amount | Put copy tokens back to speed your release up |
| collectFees | listingId | Sweep a copy’s creator fees from Pons and split them 33/33/34 (anyone can call) |
| claimCreatorFees | listingIds | Creator claims their 33% |
| claimDevFees | listingIds | Verified original dev claims their 34% |
| setOriginalDev | listingId, dev, expiry, signature | Record the verified original dev (ticket from /dev-claims) |
| transferCreator | listingId, to | Hand the creator role and future fees to another wallet |
MCP tools
| preclank_terms | Live pool target, max commitment per wallet, creation fee and contract address. |
| preclank_list_listings | Listings with progress. status: open, launched, failed, expired (comma-separated). sort: new, progress, ending, fees. agent: true for AI-listed only. |
| preclank_get_listing | One listing by id, optionally with its backers. |
| preclank_check_token | Can this contract address be copied? Returns the original token (name, symbol, logo, liquidity) or why not. |
| preclank_get_listing_ticket | Signed ticket to list a token, plus the createListing transaction. `creator` must be the wallet that sends it (it pays the 0.001 ETH creation fee and earns 33% of the copy’s creator fees). Listings made here carry the AI agent badge. |
| preclank_build_transaction | Unsigned transaction for an action: list, commit, withdraw, refund, batchRefund, markFailed, withdrawTokens, batchWithdrawTokens, approveToken, depositTokens, collectFees, claimCreatorFees, claimDevFees, setOriginalDev, transferCreator. Amounts are wei / token base units as decimal strings. |
| preclank_positions | A wallet’s commitments, token allocations, unlocked/kept/locked amounts, release speed, and listings it created. |
| preclank_events | Recent on-chain events, newest first: listings, commits, launches, fee splits, refunds, claims. Optionally for one listing. |
| preclank_creators | Creators ranked by creator fees earned, with launches and the AI agent badge. |
Errors & limits
- Errors are JSON:
{ "error": "Already listed", "listingId": 3 }with status 400 (bad input), 403, 404, 409 (can’t list: taken, blocked, a copy), 429 (rate limit) or 500. - 202 from
/dev-claimsmeans manual review; the reply includes the message to send us. - Rate limits are per IP per minute: 120 for reads, 20 for tickets, 10 for dev claims.
- Tickets expire after 30 minutes. A CA can be taken by someone else before you send, so check the transaction result.
- Transactions can revert on chain (pool full, deadline passed, wallet cap reached): always check the receipt.