Skip to content

Token API

Create tokens, export listing data, and access the verified Token List.

Endpoints

MethodPathDescription
POST/api/v2/factory/createBuild token-creation transactions via the factory
POST/api/v2/tokens/deployValidate a token deployment order before checkout
GET/api/v2/tokenlistGet verified tokens in Token List format
GET/api/v2/tokenlist/export/{symbol}/{chain}Export listing data for a symbol on a chain
GET/api/v2/config/feesGet the current fee schedule
GET/api/v2/registration/feeGet the flat claim fee

Create Token

POST /api/v2/factory/create

Build unsigned token-creation transactions via the factory contract — one transaction per requested chain. Full supply is sent to the creator wallet. Your application signs and submits each transaction.

Request Body

FieldTypeRequiredDescription
symbolstringYesToken symbol
chainsarrayYesTarget chains: [{ "chainId": 42161, "chainName": "Arbitrum" }]
creatorAddressstringYesCreator wallet address (receives full supply)
supplystringYesTotal supply
decimalsintegerNoToken decimals (default: 18)
mintablebooleanNoAllow future minting
burnablebooleanNoAllow burning
renounceAtLaunchbooleanNoRenounce ownership at launch
maxSupplystringNoMax supply cap (for mintable tokens)
metadataobjectNo{ name, logoUrl, bannerUrl, description }
liquidityPercentintegerNo1-100, % of supply for LP (atomic create+liquidity flow)
nativeAmountstringNoNative amount (wei string) for liquidity, required with liquidityPercent
lockDurationintegerNoUnix timestamp for LP unlock (requires liquidity fields)

Response Format

json
{
  "success": true,
  "transactions": [
    {
      "chainId": 42161,
      "chainName": "Arbitrum",
      "transaction": {
        "to": "0x...",
        "data": "0x...",
        "value": "10000000000000000"
      },
      "feeEstimate": { "gasLimit": "250000" }
    }
  ]
}
FieldTypeDescription
successbooleanWhether the request was processed successfully
transactionsarrayOne entry per requested chain
transactions[].transactionobjectUnsigned transaction data to sign and submit
transactions[].feeEstimateobjectEstimated gas/fees for the transaction
transactions[].errorstringPer-chain build error, if any

Code Examples

bash
curl -X POST https://api.chaindaddy.io/api/v2/factory/create \
  -H "X-API-Key: cd_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "MTK",
    "chains": [{ "chainId": 42161, "chainName": "Arbitrum" }],
    "creatorAddress": "0x1234...5678",
    "supply": "1000000000",
    "decimals": 18,
    "metadata": { "name": "My Token" }
  }'
javascript
const API_KEY = 'cd_live_abc123...';
const BASE_URL = 'https://api.chaindaddy.io';

async function createToken(tokenConfig) {
  const response = await fetch(`${BASE_URL}/api/v2/factory/create`, {
    method: 'POST',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(tokenConfig),
  });

  const data = await response.json();
  if (!data.success) throw new Error(data.error);

  // Sign and submit each per-chain transaction
  for (const entry of data.transactions) {
    if (entry.error) { console.error(entry.chainName, entry.error); continue; }
    const tx = await wallet.sendTransaction(entry.transaction);
    await tx.wait();
  }
  return data;
}

await createToken({
  symbol: 'MTK',
  chains: [{ chainId: 42161, chainName: 'Arbitrum' }],
  creatorAddress: '0x1234...5678',
  supply: '1000000000',
  decimals: 18,
  metadata: { name: 'My Token' },
});
python
import requests

API_KEY = 'cd_live_abc123...'
BASE_URL = 'https://api.chaindaddy.io'

def create_token(token_config):
    response = requests.post(
        f"{BASE_URL}/api/v2/factory/create",
        headers={
            "X-API-Key": API_KEY,
            "Content-Type": "application/json",
        },
        json=token_config,
    )
    response.raise_for_status()
    return response.json()

result = create_token({
    "symbol": "MTK",
    "chains": [{"chainId": 42161, "chainName": "Arbitrum"}],
    "creatorAddress": "0x1234...5678",
    "supply": "1000000000",
    "decimals": 18,
    "metadata": {"name": "My Token"},
})
print(f"Transactions to sign: {result['transactions']}")

Symbol Conflicts

If the symbol is already claimed on a target chain, that chain's entry fails. Use the Search API to check availability first.


Validate a Deployment Order

POST /api/v2/tokens/deploy

Validate a token deployment order (symbol format, name, chain support, supply/decimals bounds) before checkout. This endpoint validates only — it does not deploy anything.

Request Body

FieldTypeRequiredDescription
namestringYesToken name
symbolstringYesToken symbol (1-10 uppercase alphanumeric characters)
chainstringYesTarget chain key (e.g. arbitrum)
supplyintegerYesTotal supply
decimalsintegerYesToken decimals
mintablebooleanNoAllow future minting
burnablebooleanNoAllow burning
wallet_addressstringYesCreator wallet address

Response Format

json
{
  "valid": true,
  "order_action": { "type": "token_create", "chain": "arbitrum" }
}
FieldTypeDescription
validbooleanWhether the order passes validation
order_actionobjectNormalized order action for the checkout pipeline
errorsstring[]Validation errors, when valid is false

Export Listing Data

GET /api/v2/tokenlist/export/{symbol}/{chain}

Export registration/token metadata for listing applications. Requires a PRO subscription or higher (see the API feature matrix).

Parameters

ParameterLocationTypeRequiredDefaultDescription
symbolpathstringYesToken symbol
chainpathstringYesChain key (e.g. arbitrum)
formatquerystringNojsonExport format hint echoed in the response

Platform-specific formats have dedicated endpoints:

MethodPathFormat
GET/api/v2/tokenlist/cmc/{symbol}/{chain}CoinMarketCap listing format
GET/api/v2/tokenlist/gecko/{symbol}/{chain}CoinGecko listing format
GET/api/v2/tokenlist/dexscreener/{symbol}/{chain}DexScreener format

Response Format

json
{
  "symbol": "PEPE",
  "chain": "arbitrum",
  "format": "json",
  "data": {
    "name": "PEPE Token",
    "symbol": "PEPE",
    "description": "",
    "website": "",
    "twitter": "",
    "telegram": "",
    "discord": "",
    "logo": "",
    "contractAddress": "",
    "chainId": 42161
  },
  "extensions": {
    "verified": true,
    "crownId": 42
  }
}
FieldTypeDescription
dataobjectListing metadata resolved from the registration
extensions.verifiedbooleanWhether an active registration backs this token
extensions.crownIdintegerRegistration ID when verified

Code Examples

bash
# Default JSON format
curl "https://api.chaindaddy.io/api/v2/tokenlist/export/PEPE/arbitrum" \
  -H "X-API-Key: cd_live_abc123..."

# CoinMarketCap-specific format
curl "https://api.chaindaddy.io/api/v2/tokenlist/cmc/PEPE/arbitrum" \
  -H "X-API-Key: cd_live_abc123..."
javascript
async function exportListing(symbol, chain, format = 'json') {
  const url = new URL(
    `https://api.chaindaddy.io/api/v2/tokenlist/export/${symbol}/${chain}`
  );
  url.searchParams.set('format', format);

  const response = await fetch(url, {
    headers: { 'X-API-Key': API_KEY },
  });

  if (!response.ok) throw new Error(`Export failed: ${response.status}`);
  return response.json();
}

const listing = await exportListing('PEPE', 'arbitrum');
console.log(listing.extensions.verified);
python
def export_listing(symbol, chain, fmt="json"):
    response = requests.get(
        f"{BASE_URL}/api/v2/tokenlist/export/{symbol}/{chain}",
        headers={"X-API-Key": API_KEY},
        params={"format": fmt},
    )
    response.raise_for_status()
    return response.json()

listing = export_listing("PEPE", "arbitrum")
print(f"Verified: {listing['extensions']['verified']}")

For guided, submission-ready templates (real submission URLs + field checklists per aggregator), use the CLI: chaindaddy listings export --symbol PEPE --platform cmc.


Token List

GET /api/v2/tokenlist

Returns verified token registrations in the Token List standard format for wallet and DEX auto-ingestion.

Parameters

ParameterLocationTypeRequiredDescription
chainIdqueryintegerNoFilter to a single chain ID
symbolquerystringNoFilter to specific symbols (repeatable)

Response Format

json
{
  "name": "Verified Tokens",
  "timestamp": "2026-01-23T00:00:00.000Z",
  "version": {
    "major": 1,
    "minor": 0,
    "patch": 0
  },
  "keywords": ["verified", "crown", "registry"],
  "tokens": [
    {
      "chainId": 42161,
      "address": "0x6982508145454ce325ddbe47a25d4ec3d2311933",
      "name": "Pepe",
      "symbol": "PEPE",
      "decimals": 18,
      "logoURI": "https://example.com/logo.png",
      "extensions": {
        "crownId": 42
      }
    }
  ]
}
FieldTypeDescription
namestringList name
timestampstringLast update time (ISO 8601)
versionobjectSemantic version (major.minor.patch)
keywordsstring[]List tags
tokensarrayArray of token entries (Token List standard fields + extensions)

Related: GET /api/v2/tokenlist/address/{address} scopes the list to tokens owned by a wallet.

Code Examples

bash
# Full list
curl -H "X-API-Key: cd_live_abc123..." \
  "https://api.chaindaddy.io/api/v2/tokenlist"

# Arbitrum only
curl -H "X-API-Key: cd_live_abc123..." \
  "https://api.chaindaddy.io/api/v2/tokenlist?chainId=42161"
javascript
async function getTokenList(chainId) {
  const url = new URL('https://api.chaindaddy.io/api/v2/tokenlist');
  if (chainId) url.searchParams.set('chainId', String(chainId));

  const response = await fetch(url, { headers: { 'X-API-Key': API_KEY } });
  const list = await response.json();

  console.log(`${list.tokens.length} verified tokens`);
  return list.tokens;
}

const arbTokens = await getTokenList(42161);
python
def get_token_list(chain_id=None):
    params = {"chainId": chain_id} if chain_id else {}
    response = requests.get(
        f"{BASE_URL}/api/v2/tokenlist",
        headers={"X-API-Key": API_KEY},
        params=params,
    )
    response.raise_for_status()
    return response.json()["tokens"]

arb_tokens = get_token_list(chain_id=42161)
print(f"Found {len(arb_tokens)} Arbitrum tokens")

Get Fees

GET /api/v2/config/fees

Returns the current fee schedule for platform operations, driven by live pricing config.

Response Format

json
{
  "crownFee": 15,
  "createFee": 5,
  "whaleMultiplier": 1,
  "linkPrice": 10,
  "expiredClaimPrice": 25,
  "bundles": {
    "duo":      { "chains": 2, "price": 36, "savings": 4 },
    "tri":      { "chains": 3, "price": 54, "savings": 6 },
    "quad":     { "chains": 4, "price": 72, "savings": 8 },
    "allChain": { "chains": 5, "price": 90, "savings": 10 },
    "allChainEth": { "chains": 6, "price": 175, "savings": 25 }
  },
  "subscriptionTiers": {
    "pro": { "monthly": 5, "yearly": 47.88 }
  }
}
FieldTypeDescription
crownFeenumberRegistration claim fee (USD)
createFeenumberPer-chain token creation fee (USD)
linkPricenumberLegacy field — cross-chain linking is automatic and free, nothing is charged. See Cross-Chain Linking
expiredClaimPricenumberFee to reclaim an expired registration (USD)
bundlesobjectMulti-chain bundle pricing: each entry has chains, price, savings
subscriptionTiersobjectMonthly/yearly USD price per plan tier

Don't hardcode prices

Values come from live pricing config and change over time — always read this endpoint (it is cached for 5 minutes) or see the pricing docs rather than hardcoding amounts. For the flat claim fee alone, GET /api/v2/registration/fee returns { baseFeeUsd, multiplier, totalFeeUsd, currency }.


Common Recipes

Create a Token and Check Status

javascript
async function createAndMonitor(config) {
  const chain = 'arbitrum';

  // 1. Check if symbol is available
  const search = await fetch(
    `${BASE_URL}/api/v2/search?symbol=${config.symbol}&chain=${chain}`,
    { headers: { 'X-API-Key': API_KEY } }
  );
  const searchData = await search.json();
  const existing = searchData.results.find(r => r.crown?.status === 'claimed');
  if (existing) throw new Error('Symbol already claimed on this chain');

  // 2. Build the creation transaction(s)
  const create = await fetch(`${BASE_URL}/api/v2/factory/create`, {
    method: 'POST',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      symbol: config.symbol,
      chains: [{ chainId: 42161, chainName: 'Arbitrum' }],
      creatorAddress: config.creatorAddress,
      supply: config.supply,
      metadata: { name: config.name },
    }),
  });
  const { transactions } = await create.json();

  // 3. Sign and submit
  const tx = await wallet.sendTransaction(transactions[0].transaction);
  await tx.wait();

  // 4. Verify via Token List
  const list = await fetch(`${BASE_URL}/api/v2/tokenlist?chainId=42161`, {
    headers: { 'X-API-Key': API_KEY },
  });
  const { tokens } = await list.json();
  const found = tokens.find(t => t.symbol === config.symbol);
  console.log(found ? 'Listed in Token List' : 'Pending — list refreshes periodically');
}

Export Listing Data for Multiple Platforms

python
import requests
import json

def export_all_formats(symbol, chain):
    endpoints = {
        "json": f"{BASE_URL}/api/v2/tokenlist/export/{symbol}/{chain}",
        "cmc": f"{BASE_URL}/api/v2/tokenlist/cmc/{symbol}/{chain}",
        "gecko": f"{BASE_URL}/api/v2/tokenlist/gecko/{symbol}/{chain}",
        "dexscreener": f"{BASE_URL}/api/v2/tokenlist/dexscreener/{symbol}/{chain}",
    }
    exports = {}

    for fmt, url in endpoints.items():
        response = requests.get(url, headers={"X-API-Key": API_KEY})
        if response.ok:
            exports[fmt] = response.json()
            with open(f"{symbol}_{fmt}.json", "w") as f:
                json.dump(response.json(), f, indent=2)

    return exports

exports = export_all_formats("PEPE", "arbitrum")
print(f"Exported {len(exports)} formats")

Error Responses

StatusCodeDescription
400INVALID_PARAMSMissing or invalid request parameters
403FORBIDDENInvalid API key, insufficient tier, or missing PRO subscription (export)
404NOT_FOUNDSymbol not found (export only)
409ALREADY_CLAIMEDSymbol already claimed on target chain
429RATE_LIMITEDRate limit exceeded

See Authentication for details on error handling and retry strategies.