Launch a token over the API
There are two ways to launch, and each gives the token a verified page on chaindaddy.io.
| You want | Use |
|---|---|
| The token and its trading pool in one step, with nothing to pay up front, the liquidity locked, and most of the trading fees to you | The launchpad, below. This is what Create a Token does on the site. |
| A plain token with the whole supply in your wallet, where you run the liquidity yourself | /factory/create |
Every field of every call is in the API Explorer under Launchpad and Tokens. What the options mean for a creator (fee routing, boost, the pairing asset) is on Create a Token. This page is the order of calls.
Launch on the launchpad
One API key drives the whole flow: no browser and no session. Send it as X-API-Key or Authorization: Bearer cd_live_…. The key's wallet is the launch's creator and its default fee recipient; the creator in a request must be that wallet or one linked to the same account.
1. Read what the chain supports
curl -H "X-API-Key: $CHAINDADDY_API_KEY" \
"https://api.chaindaddy.io/api/v2/factory/evm/launchpad/capabilities"{
"chains": [
{
"chainId": 8453,
"label": "base",
"preOpenAuctionEngine": "dynamic-auction",
"boostEngine": "multicurve-rehype",
"operatorBroadcastEligible": true,
"numeraires": [
{ "symbol": "ETH", "address": "0x4200000000000000000000000000000000000006", "decimals": 18, "wrappedNative": true, "devBuyEligible": true },
{ "symbol": "USDC", "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "decimals": 6, "wrappedNative": false, "devBuyEligible": false }
]
}
],
"marketCapPresetsUsd": [ … ],
"boostSharePresetsBps": [ … ]
}Read it before every build and do not hardcode what it says; the values change. Three things decide what you send next:
numeraires[].addressare the only valuesnumeraire(the asset the pool is priced in) accepts on that chain. Anything else is a400.operatorBroadcastEligiblesays whether Chain Daddy will send the launch and pay its gas on that chain. When it isfalse, build the transaction and send it yourself.preOpenAuctionEnginedecides whether the pool has one fee stream or two, which changes how you collect fees.
2. Send the launch
Both routes take the same body. /broadcast signs and sends the launch for you and returns the transaction hash. /build returns an unsigned transaction for your own wallet to send.
curl -X POST https://api.chaindaddy.io/api/v2/factory/evm/launchpad/broadcast \
-H "X-API-Key: $CHAINDADDY_API_KEY" -H "Content-Type: application/json" \
-d '{
"chainId": 8453,
"name": "My Token",
"symbol": "MYT",
"tokenUri": "ipfs://…",
"initialSupply": "1000000000000000000000000000",
"numTokensToSell": "900000000000000000000000000",
"numeraire": "0x4200000000000000000000000000000000000006",
"creator": "0xYourApiKeyWallet",
"launchMode": "static",
"poolConfig": { "startMarketCapUsd": 30000, "fee": 10000 }
}'{ "chainId": 8453, "txHash": "0x…", "operator": "0x…", "predictedTokenAddress": "0x…",
"engine": "…", "launchMode": "static", "openingMarketCapUsd": 30000 }This launches a real token, and a launch cannot be undone. Rehearse it first.
/build answers { "chainId", "to", "data", "value", "predictedTokenAddress", "predictedPoolAddress", … } instead; send to, data and value from the creator's wallet. Confirm the token address from the transaction's Create event rather than trusting the prediction.
Both answers can carry supplySplit: where the supply sits when the token is created, measured by simulating the launch. pool, burn, team and other are base units and add up to totalSupply; holders lists each address. It is not numTokensToSell: a static launch puts about half the supply in the pool and sends the rest to the burn address. When the field is absent the split was not measured, so don't read it as zero. Where the supply goes
What the server enforces, each with a 400 that says which:
- Supply amounts are base units: whole tokens times 10¹⁸, as strings.
- Price the launch with
poolConfig.startMarketCapUsd. It is required when thenumerairedoes not have 18 decimals. - A boost forces
launchMode: "dynamic-auction"; the response reports it aslaunchModeOverridden: true. SendingshareBps,destinationormixwithenabled: falseis refused."burn"covers the hook's whole fee stream for the life of the pool, not onlyshareBps, and nobody can change it later. beneficiariesandcollabDealIdcannot be combined with a boost.- A
creatorAllocation(a vested team share, up to 20%) needsantiSnipe.whaleCap.enabled: false. To split it, addrecipients: up to 10 entries of{ "address", "bps" }, where eachbpsis basis points of total supply and they add up to the allocation'sbps. Everyone on that list shares the one schedule (cliffDays,unlockDays). To layer schedules, or to put different wallets on different ones, sendschedulesin place ofcliffDays,unlockDaysandrecipients: up to 4 entries of{ "cliffDays", "unlockDays", "recipients" }, at most 10 distinct wallets across them, with everybpsadding up to the allocation'sbps. A wallet can be on more than one schedule. Each schedule unlocks in a straight line from launch and can be claimed from the end of its wait, so "every week for 12 weeks" iscliffDays: 7, unlockDays: 77. The wait is at least 7 days and a whole schedule at least 28. The response'steamAllocation.scheduleslists every schedule with each wallet and the amount it vests; check it before signing, because nothing in it can be changed after the token is created. devBuy(buying your own token inside the launch transaction) works with/buildonly, because the buy is paid from the sender's funds. The response then listspreCallsto send first, in order.
3. Report a launch you sent yourself
Skip this after /broadcast. After sending a /build transaction, tell the server so the launch gets its page:
curl -X POST https://api.chaindaddy.io/api/v2/factory/evm/launchpad/confirm-launch \
-H "X-API-Key: $CHAINDADDY_API_KEY" -H "Content-Type: application/json" \
-d '{ "chainId": 8453, "txHash": "0x…" }'
# {"chainId":8453,"tokenAddress":"0x…","creator":"0x…","recorded":true}Your key's wallet must be the transaction's sender. It is safe to repeat: recorded is false the second time.
4. Get the free page
curl -H "X-API-Key: $CHAINDADDY_API_KEY" \
"https://api.chaindaddy.io/api/v2/factory/evm/launchpad/registration?chainId=8453&token=0x931fce21ddea0549db70324f44ee2db1cb9f7f22"{ "serverRegisters": true, "state": "registered", "txHash": "0xc1377ce5…8730", "tokenId": 8 }With serverRegisters: true there is nothing to sign: poll until state moves from none through queued and submitted to registered, which carries the page's tokenId. The page is then at chaindaddy.io/{symbol}.
With serverRegisters: false, or a state of failed or self_pay, register it yourself, at no charge:
POST /api/v2/payments/og/create-orderwith{ "items": [ { "chain": "8453", "symbol": "MYT", "address": "0xLaunchedToken", "type": "crown_claim" } ] }returns anorderIdfor a $0 order.POST /api/v2/payments/receiptswithpaymentIdset to thatorderId,recipientset to your wallet, and one item for the token (symbol,chainId,status: "unclaimed",address) returns a signed receipt and itsfactoryAddress.- Send the receipt's
mintCrownForExistingPaid(receipt, signature)call tofactoryAddress. The page is registered to the receipt'srecipient.
5. Collect the fees
Fees build up in the pool and are paid only when someone sends a claim transaction. Anyone may send one; it pays the parties the pool recorded, not the sender.
A pool on a multicurve-rehype chain has two fee streams on two contracts, claimed separately (two streams explains them). A static launch has only the first.
The hook's fee. Preview, then build the claim:
curl -X POST https://api.chaindaddy.io/api/v2/factory/evm/launchpad/fees \
-H "X-API-Key: $CHAINDADDY_API_KEY" -H "Content-Type: application/json" \
-d '{ "chainId": 8453, "token": "0x…" }'
# {"assetFees":"…","numeraireFees":"…","hasFees":true,"mechanism":"v4Rehype","payee":"0x…","feeDestination":"0x…"}POST …/launchpad/claim takes pool for a static launch, or poolId plus token for a dynamic-auction one, and returns the unsigned claim. The amounts are the pool's totals in base units, not one party's share. A feeDestination of 0x…dEaD means a burn launch: that stream is not yours to collect.
The pool's swap fee (your creator share). A burn does not touch this stream.
curl -X POST https://api.chaindaddy.io/api/v2/factory/evm/launchpad/fees/creator-share \
-H "X-API-Key: $CHAINDADDY_API_KEY" -H "Content-Type: application/json" \
-d '{ "chainId": 8453, "token": "0x…", "from": "0xYourWallet" }'
# {"share":"750000000000000000","assetFees":"…","numeraireFees":"…","feesAreAtLeast":true,"poolId":"0x…"}share is your part of the stream, where 1000000000000000000 is all of it. POST …/fees/claim-creator takes the same body and adds the unsigned claim (to, data, value). Send it from from: the claim pays only its sender, and sent from any other wallet it succeeds on chain and pays nobody. It refuses a zero share, so read share first.
Fees and limits
- Launching and registering the page are free. Chain Daddy takes a share of the pool's swap fee, set by the creator's plan at launch: 20% on free and monthly plans and trials, 15% on a yearly Pro, Pro+ or Developer plan, 5% on a yearly Partner or any Enterprise plan. On EVM that leaves the creator 75%, 80% or 90% after the underlying protocol's 5%. See launchpad fees.
- Launches you send yourself are not capped; you pay your own gas.
- Launches Chain Daddy sends have a weekly allowance per free account (
429when it is used up). A paid plan removes it. - The build, read and claim routes are rate-limited per wallet or IP.
Rehearse without launching
There is no public test network for launches. To see what a launch would do without sending it:
- With the CLI:
chaindaddy launchpad launch --config <file> --dry-run --rpc <url>builds the launch and simulates it against the chain. Nothing is sent (CLI reference). - With the API: call
/build, which only returns the transaction, and simulate it from the creator's wallet (eth_call, or your wallet's own preview) before you send it.
A plain token: /factory/create
POST /api/v2/factory/create returns one unsigned transaction per chain. Each creates the token, sends the whole supply to creatorAddress and registers the token's page. You sign and send each one.
curl -X POST https://api.chaindaddy.io/api/v2/factory/create \
-H "X-API-Key: $CHAINDADDY_API_KEY" -H "Content-Type: application/json" \
-d '{
"symbol": "MYTKN",
"chains": [{ "chainId": 42161, "chainName": "arbitrum" }],
"creatorAddress": "0xYourWallet",
"supply": "1000000000",
"decimals": 18,
"metadata": { "name": "My Token" },
"renounceAtLaunch": true
}'{
"success": true,
"transactions": [
{ "chainId": 42161, "chainName": "arbitrum",
"transaction": { "to": "0x…", "data": "0x…", "value": "0x…" },
"feeEstimate": { … } }
]
}Here supply is in whole tokens. value already covers the on-chain fees, so send the transaction as it is. A chain that could not be built carries an error in place of transaction, for example when the symbol is already registered there; check it per chain, because success is true either way.
To trade from the first block, add liquidity and lock it in the same transaction (EVM):
| Field | Where it comes from |
|---|---|
liquidityPercent | 1 to 100: the percent of supply paired into the pool |
nativeAmount | The native coin for the pool, in wei. Required with liquidityPercent |
dexRouter | address of a router from GET /api/v2/factory/liquidity/options?chainId={id} |
lockerAddress | address of a locker from GET /api/v2/factory/lp-lock/options?chainId={id}. Leave it out to keep the LP yourself |
lockDuration | Unix time the LP unlocks. 4294967295 locks it for good |
A chain with no locker answers { "lockers": [] }. Liquidity says which routers and lockers each chain has.
A token launched somewhere else
A token that already exists gets its page when its owner verifies it. The routes that launch through a contract Chain Daddy does not run are under Launch Venues in the Explorer.