Public API
Launch and read Arcantis tokens from a bot, an agent, or your own app.
Arcantis has a public API so you can launch a token from a script, a trading bot, an AI agent, or your own front-end. A token launched this way is identical to one launched on the website: same factory contract, same 70/20/10 fee split, same permanently locked liquidity.
No API key. No sign-up. Nothing here moves money or exposes anything private, so there is nothing to gate.
We never touch your keys
The API builds your transaction. It does not send it. You sign with a key Arcantis never sees and broadcast it yourself. There is no endpoint that launches a token for you, and there never will be — that would mean holding your private key, which would turn one break-in into everyone's loss.
Using it from an AI agent
There's a ready-made skill file — drop it into Claude Code, OpenCode, Hermes, OpenClaw or anything else that loads markdown skills, and the agent knows the whole flow without you explaining it:
https://arcantis.fun/skills/arcantis/SKILL.mdFor Claude Code, save it as .claude/skills/arcantis/SKILL.md in your project (or
~/.claude/skills/ to have it everywhere). Most other frameworks take the raw URL directly.
There's also an llms.txt at the root, which is what agents look for when they want to find their way around a site on their own.
The flow
POST /api/v1/launch/preparewith your token's details- Sign and send the
approvaltransaction it returns, if there is one - Sign and send the
launchtransaction - Read the token address from the
TokenLaunchedevent in the receipt - Optionally
POSTan image and description to the metadata endpoint
Get the current rules
curl https://arcantis.fun/api/v1/configReturns the chain, contract addresses, and the live launch rules — the fee, the supply bounds, the starting market cap. Read these rather than hardcoding them; they're read from the contract on every request and can change.
Prepare a launch
curl -X POST https://arcantis.fun/api/v1/launch/prepare \
-H 'Content-Type: application/json' \
-d '{
"name": "My Coin",
"symbol": "MYC",
"totalSupply": "1000000000",
"creatorAddress": "0xYourWallet",
"devBuyUsdc": "25",
"venue": "uniswap-v3"
}'| Field | Required | Notes |
|---|---|---|
name | yes | Up to 64 characters |
symbol | yes | Up to 16 characters |
totalSupply | yes | Whole tokens, as a string. "1000000000" is one billion |
creatorAddress | yes | The wallet that will sign |
devBuyUsdc | no | USDC of your own token to buy at launch. "25" is $25 |
feeRecipients | no | Defaults to creatorAddress. Multiple addresses split evenly |
venue | no | uniswap-v3 (default) or sushi-v3 |
Amounts are decimal strings, not raw integers — write "25" for $25, not "25000000". Values
coming back are raw integers as strings, because a JSON number would silently round a supply of
1e21.
You get back:
{
"chainId": 5042002,
"transactions": {
"approval": { "to": "0x36…", "data": "0x095ea7b3…", "value": "0" },
"launch": { "to": "0x60…", "data": "0x1f6a5b96…", "value": "0" }
},
"cost": {
"launchFeeUsdc": "1000000",
"totalUsdcRequired": "26000000",
"sufficientBalance": true
}
}approval is null when your allowance is already enough. When it isn't null, send it first and
wait for it to confirm — the factory pulls USDC from your wallet, and the launch reverts with
transfer amount exceeds allowance if you skip it.
sufficientBalance is reported, not enforced. If it's false the transaction is still built, on
the assumption you're about to fund the wallet.
Send it
import { createWalletClient, http, parseEventLogs } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const wallet = createWalletClient({ account, transport: http(RPC_URL) });
const { transactions } = await fetch(".../api/v1/launch/prepare", { ... }).then(r => r.json());
if (transactions.approval) {
const hash = await wallet.sendTransaction(transactions.approval);
await publicClient.waitForTransactionReceipt({ hash });
}
const hash = await wallet.sendTransaction(transactions.launch);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
// TokenLaunched in the receipt logs carries your new token's addressAdd an image and description
These aren't on-chain, so they're a separate call after the launch confirms:
curl -X POST https://arcantis.fun/api/tokens/0xYourToken/metadata \
-H 'Content-Type: application/json' \
-d '{ "name":"My Coin", "ticker":"MYC", "totalSupply":"1000000000000000000000000000",
"creatorAddress":"0xYourWallet", "imageUrl":"https://…", "description":"…",
"ammVenue":"uniswap-v3", "launchType":"quick" }'Do this straight after launching. It makes your token appear on the site immediately rather than waiting for the indexer, and sets the venue so the first buys route correctly.
Reading data
These are open too, and need nothing:
| Endpoint | Returns |
|---|---|
GET /api/tokens | Every live token with price, market cap, volume |
GET /api/tokens/{address} | One token, plus holders and recent trades |
GET /api/tokens/{address}/candles?interval=1h | OHLC price history |
GET /api/activity | Recent launches and trades across the platform |
GET /api/statistics | Platform totals |
GET /api/wallet/{address}/portfolio | A wallet's holdings |
Errors
Validation failures return 400 with the offending field named:
{ "error": "invalid_request", "field": "totalSupply",
"message": "totalSupply must be between … raw units (18 decimals)." }Parameters are checked against the live contract rules, so a request that returns 200 should
not revert for a reason we could have caught. Gas, balance and network conditions are still yours
to handle.
