Builders & agents
Developers
Free public read API for indexed STARC data. Launch and trade with your own wallet on Arc — there is no custodial write API. Protocol fees stay the product revenue; this API is infrastructure for bots and agents.
Model
- Read — HTTP JSON under /api/v1
- Write — on-chain only (Factory / market / SwapHelper)
- Addresses — always load GET /api/v1/config first (redeploys change them)
- Quote — create/buy with native USDC (18 dec, msg.value); pool swaps use ERC-20 USDC (6 dec)
Anon Supabase only. Cap limits (markets ≤50, trades ≤100). IP rate limits: 60/min global, 30/min on heavy routes (trades, search, profile). Short CDN/cache TTLs. Upload is rate-limited separately (same as /api/logo).
Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/config | Chain, addresses, fees — no DB |
| GET | /api/v1/markets | ?kind=&sort=&limit=&offset= |
| GET | /api/v1/markets/:id | launch_id or market 0x |
| GET | /api/v1/markets/:id/trades | Heavy · max 100 |
| GET | /api/v1/search?q= | Heavy · name/symbol |
| GET | /api/v1/stats | Cached 30s |
| GET | /api/v1/position/:market/:wallet | Indexed position |
| GET | /api/v1/profile/:address | Heavy · created + positions |
| POST | /api/v1/upload | Logo multipart (creator, file) |
| GET | /api/v1/openapi | OpenAPI 3 JSON |
OpenAPI: /api/v1/openapi. CORS is open for browser clients.
Quick read
const base = "https://starc.run/api/v1";
const config = await fetch(`${base}/config`).then((r) => r.json());
const markets = await fetch(`${base}/markets?kind=livo&limit=20`).then((r) =>
r.json(),
);
const one = await fetch(`${base}/markets/${markets.items[0].id}`).then((r) =>
r.json(),
);Agents: launch & trade
No server-side signing. Your agent holds keys (or a wallet RPC), reads config, then submits transactions. Creation fees (native USDC): Discovery / Fuse 1, LIVO 10.
1 — Create Discovery
import { createWalletClient, http, parseEther } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const cfg = await fetch(base + "/config").then((r) => r.json());
const account = privateKeyToAccount(process.env.PK);
const client = createWalletClient({
account,
chain: {
id: cfg.chain.id,
name: cfg.chain.name,
nativeCurrency: cfg.chain.nativeCurrency,
rpcUrls: { default: { http: cfg.chain.rpc } },
},
transport: http(cfg.chain.rpc[0]),
});
const factoryAbi = [{
type: "function",
name: "create",
stateMutability: "payable",
inputs: [
{ name: "name", type: "string" },
{ name: "symbol", type: "string" },
{ name: "metadataURI", type: "string" },
],
outputs: [
{ name: "launchId", type: "uint256" },
{ name: "market", type: "address" },
],
}];
await client.writeContract({
address: cfg.addresses.launchFactory,
abi: factoryAbi,
functionName: "create",
args: ["Agent Coin", "AGT", "ipfs://…"], // or https metadata / logo URL
value: parseEther(String(cfg.fees.discoveryCreationUsdc)), // 1e18 native USDC
});LIVO: createLivo with cfg.fees.livoCreationUsdc. Fuse: createFuse.
2 — Buy on bootstrap (Discovery / LIVO)
// market from GET /markets/:id → .market
const marketAbi = [{
type: "function",
name: "buy", // LIVO Phase-1 also has buyPrimary
stateMutability: "payable",
inputs: [{ name: "minTokensOut", type: "uint256" }],
outputs: [],
}];
await client.writeContract({
address: market,
abi: marketAbi,
functionName: "buy",
args: [0n], // set a real minTokensOut in production
value: parseEther("10"), // 10 native USDC
});3 — Pool swap via SwapHelper
// Approve ERC-20 USDC (6 dec) to cfg.addresses.swapHelper, then:
await client.writeContract({
address: cfg.addresses.swapHelper,
abi: [{
type: "function",
name: "exactInputSingle",
stateMutability: "nonpayable",
inputs: [
{ name: "pool", type: "address" },
{ name: "tokenIn", type: "address" },
{ name: "amountIn", type: "uint256" },
{ name: "amountOutMin", type: "uint256" },
{ name: "recipient", type: "address" },
{ name: "deadline", type: "uint256" },
],
outputs: [{ name: "amountOut", type: "uint256" }],
}],
functionName: "exactInputSingle",
args: [
pool,
cfg.quote.erc20.address,
10_000_000n, // 10 USDC (6 dec)
minOut, // required — 0 reverts
account.address,
BigInt(Math.floor(Date.now() / 1000) + 300),
],
});Rate limits & cost
- 60 requests/minute per IP across all /api/v1
- 30/minute additional cap on trades, search, profile
- Upload: 8/minute (shared with logo route)
- Responses include Cache-Control — clients and edges should honor it
- 429 responses set Retry-After: 30
Prefer /config + list endpoints over polling trades every second. Index lag is normal — confirm critical state on-chain when needed.
Related
- Primitives — Discovery, Fuse, LIVO
- Fees
- Wallet & network
- Security