Appearance
Token API
Create tokens, export listing data, and access the verified Token List.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v2/factory/create | Build token-creation transactions via the factory |
POST | /api/v2/tokens/deploy | Validate a token deployment order before checkout |
GET | /api/v2/tokenlist | Get 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/fees | Get the current fee schedule |
GET | /api/v2/registration/fee | Get the flat claim fee |
Create Token
POST /api/v2/factory/createBuild 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
| Field | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Token symbol |
chains | array | Yes | Target chains: [{ "chainId": 42161, "chainName": "Arbitrum" }] |
creatorAddress | string | Yes | Creator wallet address (receives full supply) |
supply | string | Yes | Total supply |
decimals | integer | No | Token decimals (default: 18) |
mintable | boolean | No | Allow future minting |
burnable | boolean | No | Allow burning |
renounceAtLaunch | boolean | No | Renounce ownership at launch |
maxSupply | string | No | Max supply cap (for mintable tokens) |
metadata | object | No | { name, logoUrl, bannerUrl, description } |
liquidityPercent | integer | No | 1-100, % of supply for LP (atomic create+liquidity flow) |
nativeAmount | string | No | Native amount (wei string) for liquidity, required with liquidityPercent |
lockDuration | integer | No | Unix 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" }
}
]
}| Field | Type | Description |
|---|---|---|
success | boolean | Whether the request was processed successfully |
transactions | array | One entry per requested chain |
transactions[].transaction | object | Unsigned transaction data to sign and submit |
transactions[].feeEstimate | object | Estimated gas/fees for the transaction |
transactions[].error | string | Per-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/deployValidate 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
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Token name |
symbol | string | Yes | Token symbol (1-10 uppercase alphanumeric characters) |
chain | string | Yes | Target chain key (e.g. arbitrum) |
supply | integer | Yes | Total supply |
decimals | integer | Yes | Token decimals |
mintable | boolean | No | Allow future minting |
burnable | boolean | No | Allow burning |
wallet_address | string | Yes | Creator wallet address |
Response Format
json
{
"valid": true,
"order_action": { "type": "token_create", "chain": "arbitrum" }
}| Field | Type | Description |
|---|---|---|
valid | boolean | Whether the order passes validation |
order_action | object | Normalized order action for the checkout pipeline |
errors | string[] | 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
| Parameter | Location | Type | Required | Default | Description |
|---|---|---|---|---|---|
symbol | path | string | Yes | — | Token symbol |
chain | path | string | Yes | — | Chain key (e.g. arbitrum) |
format | query | string | No | json | Export format hint echoed in the response |
Platform-specific formats have dedicated endpoints:
| Method | Path | Format |
|---|---|---|
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
}
}| Field | Type | Description |
|---|---|---|
data | object | Listing metadata resolved from the registration |
extensions.verified | boolean | Whether an active registration backs this token |
extensions.crownId | integer | Registration 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/tokenlistReturns verified token registrations in the Token List standard format for wallet and DEX auto-ingestion.
Parameters
| Parameter | Location | Type | Required | Description |
|---|---|---|---|---|
chainId | query | integer | No | Filter to a single chain ID |
symbol | query | string | No | Filter 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
}
}
]
}| Field | Type | Description |
|---|---|---|
name | string | List name |
timestamp | string | Last update time (ISO 8601) |
version | object | Semantic version (major.minor.patch) |
keywords | string[] | List tags |
tokens | array | Array 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/feesReturns 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 }
}
}| Field | Type | Description |
|---|---|---|
crownFee | number | Registration claim fee (USD) |
createFee | number | Per-chain token creation fee (USD) |
linkPrice | number | Legacy field — cross-chain linking is automatic and free, nothing is charged. See Cross-Chain Linking |
expiredClaimPrice | number | Fee to reclaim an expired registration (USD) |
bundles | object | Multi-chain bundle pricing: each entry has chains, price, savings |
subscriptionTiers | object | Monthly/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
| Status | Code | Description |
|---|---|---|
400 | INVALID_PARAMS | Missing or invalid request parameters |
403 | FORBIDDEN | Invalid API key, insufficient tier, or missing PRO subscription (export) |
404 | NOT_FOUND | Symbol not found (export only) |
409 | ALREADY_CLAIMED | Symbol already claimed on target chain |
429 | RATE_LIMITED | Rate limit exceeded |
See Authentication for details on error handling and retry strategies.