Skip to content

Launch a token over the API ​

There are two ways to launch, and each gives the token a verified page on chaindaddy.io.

You wantUse
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 youThe 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 ​

bash
curl -H "X-API-Key: $CHAINDADDY_API_KEY" \
  "https://api.chaindaddy.io/api/v2/factory/evm/launchpad/capabilities"
json
{
  "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[].address are the only values numeraire (the asset the pool is priced in) accepts on that chain. Anything else is a 400.
  • operatorBroadcastEligible says whether Chain Daddy will send the launch and pay its gas on that chain. When it is false, build the transaction and send it yourself.
  • preOpenAuctionEngine decides 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.

bash
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 }
  }'
json
{ "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 the numeraire does not have 18 decimals.
  • A boost forces launchMode: "dynamic-auction"; the response reports it as launchModeOverridden: true. Sending shareBps, destination or mix with enabled: false is refused. "burn" covers the hook's whole fee stream for the life of the pool, not only shareBps, and nobody can change it later.
  • beneficiaries and collabDealId cannot be combined with a boost.
  • A creatorAllocation (a vested team share, up to 20%) needs antiSnipe.whaleCap.enabled: false. To split it, add recipients: up to 10 entries of { "address", "bps" }, where each bps is basis points of total supply and they add up to the allocation's bps. Everyone on that list shares the one schedule (cliffDays, unlockDays). To layer schedules, or to put different wallets on different ones, send schedules in place of cliffDays, unlockDays and recipients: up to 4 entries of { "cliffDays", "unlockDays", "recipients" }, at most 10 distinct wallets across them, with every bps adding up to the allocation's bps. 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" is cliffDays: 7, unlockDays: 77. The wait is at least 7 days and a whole schedule at least 28. The response's teamAllocation.schedules lists 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 /build only, because the buy is paid from the sender's funds. The response then lists preCalls to 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:

bash
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 ​

bash
curl -H "X-API-Key: $CHAINDADDY_API_KEY" \
  "https://api.chaindaddy.io/api/v2/factory/evm/launchpad/registration?chainId=8453&token=0x931fce21ddea0549db70324f44ee2db1cb9f7f22"
json
{ "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:

  1. POST /api/v2/payments/og/create-order with { "items": [ { "chain": "8453", "symbol": "MYT", "address": "0xLaunchedToken", "type": "crown_claim" } ] } returns an orderId for a $0 order.
  2. POST /api/v2/payments/receipts with paymentId set to that orderId, recipient set to your wallet, and one item for the token (symbol, chainId, status: "unclaimed", address) returns a signed receipt and its factoryAddress.
  3. Send the receipt's mintCrownForExistingPaid(receipt, signature) call to factoryAddress. The page is registered to the receipt's recipient.

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:

bash
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.

bash
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 (429 when 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.

bash
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
  }'
json
{
  "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):

FieldWhere it comes from
liquidityPercent1 to 100: the percent of supply paired into the pool
nativeAmountThe native coin for the pool, in wei. Required with liquidityPercent
dexRouteraddress of a router from GET /api/v2/factory/liquidity/options?chainId={id}
lockerAddressaddress of a locker from GET /api/v2/factory/lp-lock/options?chainId={id}. Leave it out to keep the LP yourself
lockDurationUnix 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.