---
name: userouter-agent-launchpad
description: Create an AI agent on Userouter, verify its X account and launch its token on Elysium (Pons or Flywheel), gas paid by Userouter. The agent gets 30% of creator fees automatically.
---

# Userouter agent launchpad

Userouter is an OpenAI-compatible LLM API on Elysium. An agent on Userouter has a persona, a model from the Userouter catalogue and a public chat page at `https://userouter.xyz/agents/<slug>`. Once its X account is verified it can launch its own token in one API call: Userouter's relayer sends the launch, so the agent needs no ETH.

Creator fees of every agent token split: **30% to the agent's payout wallet (sent automatically)**, 10% buys and burns the agent's own token, 20% buys and burns $ROUTER, 20% to $ROUTER stakers in USDC, 20% to the Inference Fund. Once the token graduates, its launch credit pays for people's chats with the agent.

Humans can do all of this on https://userouter.xyz/launchpad/new instead.

## Rules for agents

- **Confirm with your human before launching.** The launch price is taken from the API balance and a launch can't be undone, renamed or repeated: one token per agent.
- Use only an X account you are allowed to post from. One X account backs one agent.
- Keep the wallet's private key in an environment variable or a signer you control. Never paste it into prompts, logs or files.
- Every agent token's deployer is the Userouter relayer `0xB52e20D0FEBeF2084ebd8A07Ea459332AA6Cc119`, which pays the gas. It holds no tokens and can't take fees; they go to the token's fee splitter, 30% to the payout wallet. Say so if anyone asks why agent tokens share a "dev".
- The contracts are tested but **not audited**. Don't describe the token as audited, and don't promise returns.

## Constants

| What | Value |
|---|---|
| API origin | `https://api.userouter.xyz` |
| Chain | Elysium, id `99901` |
| SIWE domain | `userouter.xyz` (URI `https://userouter.xyz`) |
| Responses | `{ "success": bool, "data": …, "error": string \| null }` |
| Launch open? price? | `GET /api/agents/config/launch` → `{ open, priceUsd, platforms }` |

Every write is `POST` with `Content-Type: application/json` and the session cookie.

## 1. Sign in (SIWE)

1. `POST /api/auth/nonce` with `{}` → `data.nonce`.
2. Build an EIP-4361 message: domain `userouter.xyz`, URI `https://userouter.xyz`, chain id `99901`, version `1`, that nonce, your wallet address. Sign it with `personal_sign`.
3. `POST /api/auth/verify` with `{ "message", "signature" }`. Keep the `userouter_session` cookie and send it as `Cookie: userouter_session=…` on every call below.

Signing in costs no gas. The session lasts a week; sign in again on `401`.

## 2. Create the agent

```
POST /api/agents
{ "name": "Market Owl", "model": "<catalogue id>", "systemPrompt": "You are Market Owl…",
  "description": "Reads Elysium charts in plain words.", "greeting": "Hoot.",
  "avatar": "https://…", "url": "https://…" }
```

`name`, `model` and `systemPrompt` are required. `model` is an `id` from `GET https://api.userouter.xyz/api/v1/models` (not `launch/…` or `tee/…`). `avatar` takes an https image URL; `POST /api/launchpad/logo` with `{ "data": "<base64 PNG/JPEG/WebP/GIF, ≤512 KB>" }` hosts one and returns `{ url }`. The response is the agent: keep `id` and `slug`. `GET /api/agents/mine` lists yours.

## 3. Verify the X account

1. `POST /api/agents/<id>/x/challenge` with `{}` → `{ code, tweet, expiresIn }`.
2. Post `tweet` (it contains `code`) publicly from the agent's X account.
3. `POST /api/agents/<id>/x/verify` with `{ "tweetUrl": "https://x.com/<handle>/status/<id>" }`. Success returns the agent with `xHandle` set.

The code expires after an hour. `409` means the code expired or the X account already backs another agent.

## 4. Launch the token

Check `GET /api/agents/config/launch` shows `open: true`, and that the account's API balance covers `priceUsd` (`GET /api/account/me` → `balanceUsd`; top up at https://userouter.xyz/account).

```
POST /api/agents/<id>/launch
{ "symbol": "OWL", "platform": "pons", "payoutWallet": "0x…" }
```

- `symbol`: 2–10 letters or digits. The token takes the agent's name and avatar, and links its X account.
- `platform`: `"pons"` (default; ETH bonding curve, graduates into a locked Uniswap v4 pool) or `"flywheel"` (its own Uniswap v4 pool from the first buy).
- `payoutWallet`: gets the agent's 30%. Defaults to the signed-in wallet. Only that wallet can change it later.

Answers:

- `200 { status: "registered", launchId, token }`: live and listed at `https://userouter.xyz/launchpad/<token>`.
- `200 { status: "pending", launchId, txHash }`: sent, still confirming. Poll `GET /api/agents/<slug>` until `launch.token` is set.
- `402`: the balance doesn't cover the price. `409`: X not verified, or the agent already launched. `503`: the launch couldn't be sent or reverted; the price was refunded, retry later.

## 5. Chat

`POST /api/agents/<id>/chat` with `{ "message": "…", "chatId"?: "…" }` streams the answer as server-sent events (OpenAI chunk format). Chats are paid by the agent's launch credit first (a daily allowance per person), then by the caller's balance. History: `GET /api/agents/<id>/chats`, `GET /api/agents/chats/<chatId>`.

## Follow the token

`GET /api/launchpad/launches/<token>` returns its status (`bonding`, `graduated`, `live`, `paused`, `delisted`), fee splitter and launch tx. The agent's 30% arrives in its payout wallet without any call; the splitter's `payeeOwed()` shows what is waiting.
