Build on kiwi.rich
Everything needed to list, index, quote, and trade kiwi.rich markets in terminals, bots, scanners, and analytics products.
Start here
Two sources, one canonical market
Watch the contracts for immediate launch, trade, and graduation events. Use the public API to enrich those events with images, socials, normalized prices, holders, candles, and historical activity. Never delay new-pair discovery on an API request.
Onchain events
Canonical and lowest latency. Use for New Pairs, live trades, Final Stretch, and migration alerts.
Read API
Indexed and normalized. Use for rendering market cards, charts, token pages, holders, and metadata.
Contracts
Arc mainnet deployments
Index both factories. V2 is the current launch version; V1 markets remain live and must continue to be discoverable and tradeable.
V2 factory
Primary · block 11,202,050
V1 factory
Legacy · block 11,075,665
System USDC
ERC-20 interface · 6 decimals
Permit router
Optional atomic USDC permit
Sponsored router
Zero-buy creator authorization
Chain ID
5042
Launch token
18 decimals
Address suffix
0000
New pairs
Discover every launch
Subscribe to LaunchCreated on both factories. The event contains the token, curve, creator, display metadata URI, and the complete immutable economics for that factory version.
import { createPublicClient, http, parseAbiItem } from "viem";
const FACTORIES = [
"0x8Ac834b6A56278f4cf4a6D2E66F332a5348e12Dc", // V2
"0x74B79eA7C8c8621979c5aB9710f27B70aBB543E5", // V1
] as const;
const launchCreated = parseAbiItem(
"event LaunchCreated(address indexed token, address indexed curve, address indexed creator, string name, string symbol, string metadataURI, (uint256 totalSupply, uint256 curveSupply, uint256 virtualUsdc, uint256 graduationTarget, uint16 curveFeeBps, uint16 poolFeeBps, uint16 creatorFeeShareBps, bool burnSurplusTokens, address usdc, address protocolTreasury) config"
);
const logs = await client.getLogs({
address: FACTORIES,
event: launchCreated,
fromBlock: 11075665n,
toBlock: "latest",
});Canonical validation
A token is a kiwi.rich launch only when at least one published factory returns a non-zero curve fromcurveForToken(token).
Ordering
Order New Pairs by block number and log index. Persist the last finalized cursor and rewind on a chain reorganization instead of relying on timestamps alone.
import { zeroAddress } from "viem";
async function resolveKiwiMarket(token) {
for (const factory of FACTORIES) {
const curve = await client.readContract({
address: factory,
abi: factoryAbi,
functionName: "curveForToken",
args: [token],
});
if (curve !== zeroAddress) {
const pool = await client.readContract({
address: factory,
abi: factoryAbi,
functionName: "poolForToken",
args: [token],
});
return { factory, curve, pool };
}
}
return null;
}State machine
Curve to permanent liquidity
A market has exactly two phases. Graduation happens atomically inside the final curve buy, creates one permanent constant-product pool, and closes curve trading permanently.
0 · Bonding curve
New / Final StretchVenue is curveForToken(token). Progress equals the real curve USDC reserve divided by that launch's graduation target.
1 · Permanent pool
MigratedVenue is poolForToken(token). Liquidity has no withdrawal, transfer, decrease, or LP-owner path.
LaunchCreatedInsert the token into New Pairs immediately.Buy / SellUpdate price, volume, transactions, reserves, and progress.LaunchGraduatedMove the token to Migrated and switch execution to the emitted pool.HTTP API
Normalized market data
The API is read-only, versioned, and CORS-enabled. Cache it for presentation, but use contract events for latency-sensitive alerts and transaction decisions.
# Launchpad configuration and event signatures
curl https://kiwi.rich/api/v1/launchpad
# Bounded newest-first market snapshot
curl "https://kiwi.rich/api/v1/markets?limit=24"
# Complete normalized data for one canonical token
curl https://kiwi.rich/api/v1/token/0x6d1b30b0795ee3745d9648d286caebf905390000
# Machine-readable interfaces
curl https://kiwi.rich/api/v1/abis
curl https://kiwi.rich/api/v1/openapiExecution
Quote and trade the active venue
Read the phase immediately before quoting. Curve and pool venues expose the same buy and sell entrypoint names, while their quote return shapes differ. Integrators sign and submit transactions from their own wallets; kiwi.rich never receives private keys.
quoteBuy(usdcIn)USDC input uses 6 decimalsbuy(usdcIn, minTokensOut)Approve system USDC to the active venuequoteSell(tokensIn)Token input uses 18 decimalssell(tokensIn, minUsdcOut)Approve the launch token to the active venueimport { erc20Abi, parseUnits } from "viem";
const usdcIn = parseUnits("100", 6);
const tokenData = await fetch(
`https://kiwi.rich/api/v1/token/${token}`
).then((response) => response.json());
const venue = tokenData.market.venue;
const onCurve = tokenData.market.phase === "bonding_curve";
const venueAbi = onCurve ? bondingCurveAbi : graduatedPoolAbi;
const quote = await publicClient.readContract({
address: venue,
abi: venueAbi,
functionName: "quoteBuy",
args: [usdcIn],
});
const tokensOut = quote[0];
const minTokensOut = (tokensOut * 9_900n) / 10_000n; // 1% slippage
await walletClient.writeContract({
address: "0x3600000000000000000000000000000000000000",
abi: erc20Abi,
functionName: "approve",
args: [venue, usdcIn],
});
await walletClient.writeContract({
address: venue,
abi: venueAbi,
functionName: "buy",
args: [usdcIn, minTokensOut],
value: 0n,
});Graduation edge case
A final curve buy may consume less USDC than the supplied maximum. Use the curve's fullquoteBuy result when accounting for exact spend. After every confirmed trade, reread phase and pool before constructing the next order.
Token presentation
Images, links, and descriptions
Read metadataURI() from the token or use the normalized token endpoint. Metadata is offchain presentation data; the token address, creator, economics, and market venues must always come from the contracts.
{
"name": "Kiwi Cat",
"symbol": "kcat",
"description": "A token launched on Arc.",
"image": "https://.../logo.png",
"x": "https://x.com/...",
"telegram": "https://t.me/...",
"website": "https://..."
}Image, description, and social URLs may be absent on legacy launches. Treat unknown fields as optional and never infer canonical status from the metadata host or address suffix alone.
Production checklist
Rules that keep integrations correct
These constraints matter for every terminal, bot, and scanner integration.
- Index V2 and V1 from their exact deployment blocks.
- Validate tokens through factory storage, not the 0000 suffix.
- Use 6 decimals for ERC-20 USDC and 18 decimals for native gas USDC.
- Send zero native value to buy and sell contract calls.
- Read each launch's emitted economics instead of hardcoding V2 values.
- Handle reorgs and deduplicate events by transaction hash plus log index.
- Switch venue only after the canonical graduation event confirms.
- Do not label the permanent pool as Uniswap or expose LP withdrawal controls.
Built an integration?
Show us on X