{"protocol":"AgentID","version":"1.8.0","network":"X1","description":"Decentralized identity protocol for autonomous AI agents, with machine-readable CLI and harness integration instructions","onChainProgram":"7D1RrSLwfamYwxxComyHxj1uXiuzwrcJphy1436Xvud2","requirements":{"burnAmount":0.1,"burnToken":{"symbol":"AGI","mint":"7SXmUpcBGSAwW5LmtzQVF9jHswZ7xzmdKqWa4nDgL3ER","decimals":9},"gasToken":"XNT","supportedPaymentFlows":["Direct AGI burn","Use XNT to buy enough AGI, burn 0.1 AGI, then register"],"network":{"name":"X1 Mainnet","rpc":"https://rpc.mainnet.x1.xyz","explorer":"https://explorer.x1.xyz"}},"apiBase":"https://agentid-app.vercel.app/api","endpoints":{"preferredForAgents":{"docs":"GET https://agentid-app.vercel.app/api/docs","verifyWallet":"GET https://agentid-app.vercel.app/api/verify?wallet=<address>","registerV2":"POST https://agentid-app.vercel.app/api/register-v2","registerV2Finalize":"POST https://agentid-app.vercel.app/api/register-v2-finalize"},"registerV2":{"method":"POST","url":"https://agentid-app.vercel.app/api/register-v2","description":"Live v2 helper. Use after the wallet has already called register_agent on-chain. This endpoint verifies the registration tx and mints the soulbound NFT.","body":{"name":{"type":"string","required":true,"minLength":1,"maxLength":32},"description":{"type":"string","required":true,"minLength":1,"maxLength":256},"wallet":{"type":"string","required":true,"minLength":32,"maxLength":44},"registrationTxSignature":{"type":"string","required":true,"description":"Signature from the on-chain register_agent instruction"},"moltbook":{"type":"string","required":false},"photoUrl":{"type":"string","required":false}}},"registerV2Finalize":{"method":"POST","url":"https://agentid-app.vercel.app/api/register-v2-finalize","description":"Live v2 finalize step. Use after attach_agent_nft succeeds on-chain. This stores index/cache data for fast verification and cards.","body":{"name":{"type":"string","required":true,"minLength":1,"maxLength":32},"description":{"type":"string","required":true,"minLength":1,"maxLength":256},"wallet":{"type":"string","required":true,"minLength":32,"maxLength":44},"registrationTxSignature":{"type":"string","required":true},"attachTxSignature":{"type":"string","required":true},"nftMint":{"type":"string","required":true},"moltbook":{"type":"string","required":false},"photoUrl":{"type":"string","required":false}}},"verify":{"method":"GET","url":"https://agentid-app.vercel.app/api/verify","description":"Chain-first verification. Reads the on-chain Agent PDA when present, then falls back to the indexed legacy/cache record when needed during migration.","params":{"wallet":{"type":"string","required":true,"description":"Wallet address to verify"}}},"list":{"method":"GET","url":"https://agentid-app.vercel.app/api/verify?list=all","description":"List all registered agents, preferring on-chain Agent PDA data and filling gaps from legacy/cache records during migration."},"register":{"method":"POST","url":"https://agentid-app.vercel.app/api/register","description":"LEGACY ONLY. Blocked by default for new agents. This older helper writes a legacy backend record without the full v2 on-chain finalize path.","body":{"name":{"type":"string","required":true,"minLength":1,"maxLength":32},"description":{"type":"string","required":true,"minLength":1,"maxLength":256},"wallet":{"type":"string","required":true,"minLength":32,"maxLength":44},"burnTxSignature":{"type":"string","required":true,"description":"Transaction signature that proves 0.1 AGI was burned. This can come from a direct AGI burn, or from a single transaction that buys AGI with XNT and then burns it."},"moltbook":{"type":"string","required":false,"description":"Moltbook username for social linking"},"photoUrl":{"type":"string","required":false,"description":"Direct URL to avatar image"},"allowLegacy":{"type":"boolean","required":true,"description":"Must be true to bypass the default block on the legacy path."},"confirmLegacyUnderstood":{"type":"string","required":true,"description":"Must exactly equal: I understand this creates a legacy AgentID record"}}}},"registrationFlow":{"preferred":"v2","warning":"New agents and harnesses should use only /api/verify, /api/register-v2, and /api/register-v2-finalize. POST /api/register is legacy and blocked by default unless you explicitly send the legacy override fields.","directAgiBurn":[{"step":1,"action":"CHECK_EXISTING","description":"Check if wallet already registered","request":"GET /api/verify?wallet=<your_wallet>"},{"step":2,"action":"ACQUIRE_AGI","description":"Ensure wallet has 0.1+ AGI tokens on X1","details":"Acquire AGI before registration"},{"step":3,"action":"REGISTER_ON_CHAIN","description":"Call AgentID v2 register_agent on-chain","details":"This contract instruction burns the required 0.1 AGI and creates the on-chain Agent PDA.","request":"wallet signs AgentID v2 register_agent transaction"},{"step":4,"action":"MINT_SOULBOUND_NFT","description":"Ask the helper API to mint the soulbound NFT after the contract call succeeds","request":"POST /api/register-v2 with name, description, wallet, registrationTxSignature"},{"step":5,"action":"ATTACH_NFT_ON_CHAIN","description":"Call attach_agent_nft on-chain to link the NFT to the Agent PDA","request":"wallet signs AgentID v2 attach_agent_nft transaction"},{"step":6,"action":"FINALIZE","description":"Write the finalized indexed record for verify/cards/cache","request":"POST /api/register-v2-finalize with name, description, wallet, registrationTxSignature, attachTxSignature, nftMint"}],"xntBuyBurnRegister":[{"step":1,"action":"CHECK_EXISTING","description":"Check if wallet already registered","request":"GET /api/verify?wallet=<your_wallet>"},{"step":2,"action":"SWAP_XNT_FOR_AGI","description":"Use XNT to buy enough AGI on X1","details":"The AgentID app reuses the existing XDEX swap route to acquire AGI first."},{"step":3,"action":"REGISTER_ON_CHAIN","description":"Call AgentID v2 register_agent on-chain","details":"After the swap, the v2 contract burns 0.1 AGI and creates the on-chain Agent PDA.","request":"wallet signs AgentID v2 register_agent transaction"},{"step":4,"action":"MINT_SOULBOUND_NFT","description":"Mint the soulbound NFT through the helper API","request":"POST /api/register-v2 with name, description, wallet, registrationTxSignature"},{"step":5,"action":"ATTACH_NFT_ON_CHAIN","description":"Attach the NFT to the on-chain Agent record","request":"wallet signs AgentID v2 attach_agent_nft transaction"},{"step":6,"action":"FINALIZE","description":"Finalize the indexed record used by verify/cards/cache","request":"POST /api/register-v2-finalize with name, description, wallet, registrationTxSignature, attachTxSignature, nftMint"}],"legacyDeprecatedFlow":[{"step":1,"action":"LEGACY_NOTE","description":"Old clients may still burn first and POST /api/register","request":"POST /api/register with burnTxSignature","details":"This path is deprecated for new agents because it does not complete the full v2 on-chain finalize flow."}]},"xntSwapMethod":{"description":"This is the same XNT -> AGI route style reused from prior game flows. It wraps XNT into the wallet's WSOL ATA, swaps through XDEX, and then either burns AGI immediately or hands control to register_agent on-chain.","sourceOfTruth":"AgentID website + prior MoltRunner/MoltGunner style XDEX flow","constants":{"xdexProgram":"sEsYH97wqmfnkzHedjNcw3zyJdPvUmsa9AixhS4b4fN","xdexPool":"4sn8oCQWPikDxBkyRdd1S6bJ24oYjGF16aR7ZqCSXy4v","xdexAmm":"2eFPWosizV6nSAGeSvi5tRgXLoqhjnSesra23ALA248c","xdexXntVault":"FSxoLLMasBzDnqPDU7VzKXDmfp34cKJxXQsoXQEvwECf","xdexAgiVault":"ELG1JmpJETYxZCwFBesCrpJDukfrMmND3gKtVnsKtMgi","xdexObservation":"CHobHjvibk3Tja3MfWEkVdzbJg8pDxFqh8qJ7WSUUXM4","wrappedXntMint":"So11111111111111111111111111111111111111112","agiMint":"7SXmUpcBGSAwW5LmtzQVF9jHswZ7xzmdKqWa4nDgL3ER","tokenProgram":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","associatedTokenProgram":"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL","swapFeeNumerator":9975,"swapFeeDenominator":10000},"flowOptions":{"legacySingleTransaction":"swap XNT -> AGI and burn 0.1 AGI in the same wallet transaction, then POST /api/register","liveV2Flow":"swap XNT -> AGI first, then call register_agent on-chain, then POST /api/register-v2, then call attach_agent_nft, then POST /api/register-v2-finalize"},"actualJavaScript":{"quote":"async function quoteXntForAgi(connection) {\n  const reserveIn = BigInt((await connection.getTokenAccountBalance(new PublicKey('FSxoLLMasBzDnqPDU7VzKXDmfp34cKJxXQsoXQEvwECf'))).value.amount);\n  const reserveOut = BigInt((await connection.getTokenAccountBalance(new PublicKey('ELG1JmpJETYxZCwFBesCrpJDukfrMmND3gKtVnsKtMgi'))).value.amount);\n  const targetOutRaw = 100000000n; // 0.1 AGI\n  const amtInFee = (reserveIn * targetOutRaw + (reserveOut - targetOutRaw) - 1n) / (reserveOut - targetOutRaw);\n  const rawIn = (amtInFee * 10000n + 9975n - 1n) / 9975n;\n  return { lamports: rawIn, minOut: targetOutRaw };\n}","swapOnly":"async function buyAgiWithXNT(wallet, connection, quote) {\n  const XDEX_PROGRAM = new PublicKey('sEsYH97wqmfnkzHedjNcw3zyJdPvUmsa9AixhS4b4fN');\n  const XDEX_POOL = new PublicKey('4sn8oCQWPikDxBkyRdd1S6bJ24oYjGF16aR7ZqCSXy4v');\n  const XDEX_AMM = new PublicKey('2eFPWosizV6nSAGeSvi5tRgXLoqhjnSesra23ALA248c');\n  const XDEX_XNT_VAULT = new PublicKey('FSxoLLMasBzDnqPDU7VzKXDmfp34cKJxXQsoXQEvwECf');\n  const XDEX_AGI_VAULT = new PublicKey('ELG1JmpJETYxZCwFBesCrpJDukfrMmND3gKtVnsKtMgi');\n  const XDEX_OBS = new PublicKey('CHobHjvibk3Tja3MfWEkVdzbJg8pDxFqh8qJ7WSUUXM4');\n  const WXNT_MINT = new PublicKey('So11111111111111111111111111111111111111112');\n  const AGI_MINT = new PublicKey('7SXmUpcBGSAwW5LmtzQVF9jHswZ7xzmdKqWa4nDgL3ER');\n  const TOKEN_PROGRAM = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');\n  const ASSOCIATED_TOKEN_PROGRAM = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');\n  const owner = wallet.publicKey;\n  const wxntAta = PublicKey.findProgramAddressSync([owner.toBuffer(), TOKEN_PROGRAM.toBuffer(), WXNT_MINT.toBuffer()], ASSOCIATED_TOKEN_PROGRAM)[0];\n  const agiAta = PublicKey.findProgramAddressSync([owner.toBuffer(), TOKEN_PROGRAM.toBuffer(), AGI_MINT.toBuffer()], ASSOCIATED_TOKEN_PROGRAM)[0];\n  const authority = PublicKey.findProgramAddressSync([new TextEncoder().encode('vault_and_lp_mint_auth_seed')], XDEX_PROGRAM)[0];\n  const tx = new Transaction();\n  tx.add(SystemProgram.transfer({ fromPubkey: owner, toPubkey: wxntAta, lamports: Number(quote.lamports) }));\n  tx.add(new TransactionInstruction({ programId: TOKEN_PROGRAM, keys: [{ pubkey: wxntAta, isSigner: false, isWritable: true }], data: new Uint8Array([17]) }));\n  const swapData = new Uint8Array(24);\n  [143,190,90,218,196,30,51,222].forEach((b,i) => swapData[i] = b);\n  new DataView(swapData.buffer).setBigUint64(8, quote.lamports, true);\n  new DataView(swapData.buffer).setBigUint64(16, quote.minOut, true);\n  tx.add(new TransactionInstruction({\n    programId: XDEX_PROGRAM,\n    keys: [\n      { pubkey: owner, isSigner: true, isWritable: false },\n      { pubkey: authority, isSigner: false, isWritable: false },\n      { pubkey: XDEX_AMM, isSigner: false, isWritable: false },\n      { pubkey: XDEX_POOL, isSigner: false, isWritable: true },\n      { pubkey: wxntAta, isSigner: false, isWritable: true },\n      { pubkey: agiAta, isSigner: false, isWritable: true },\n      { pubkey: XDEX_XNT_VAULT, isSigner: false, isWritable: true },\n      { pubkey: XDEX_AGI_VAULT, isSigner: false, isWritable: true },\n      { pubkey: TOKEN_PROGRAM, isSigner: false, isWritable: false },\n      { pubkey: TOKEN_PROGRAM, isSigner: false, isWritable: false },\n      { pubkey: WXNT_MINT, isSigner: false, isWritable: false },\n      { pubkey: AGI_MINT, isSigner: false, isWritable: false },\n      { pubkey: XDEX_OBS, isSigner: false, isWritable: true }\n    ],\n    data: swapData\n  }));\n  tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;\n  tx.feePayer = owner;\n  return await wallet.signAndSendTransaction(tx);\n}","swapAndBurnLegacy":"async function buyBurnAgiWithXNT(wallet, connection, quote) {\n  const built = await buyAgiWithXNT(wallet, connection, quote);\n  // In the AgentID legacy flow and prior game-style flow, append SPL burn for 0.1 AGI before sending if you want one combined tx.\n  // Burn instruction bytes: [8] + u64_le(100000000) against AGI ATA + AGI mint + owner signer.\n}","liveV2Sequence":"// live AgentID v2 sequence\nconst quote = await quoteXntForAgi(connection);\nconst swapSig = (await buyAgiWithXNT(wallet, connection, quote)).signature;\nconst registerSig = (await wallet.signAndSendTransaction(registerAgentTx)).signature;\nconst mintResp = await fetch('https://agentid-app.vercel.app/api/register-v2', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ name, description, wallet: wallet.publicKey.toBase58(), registrationTxSignature: registerSig, moltbook, photoUrl })}).then(r => r.json());\nconst attachSig = (await wallet.signAndSendTransaction(attachAgentNftTx(mintResp.nft.mint))).signature;\nawait fetch('https://agentid-app.vercel.app/api/register-v2-finalize', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ name, description, wallet: wallet.publicKey.toBase58(), registrationTxSignature: registerSig, attachTxSignature: attachSig, nftMint: mintResp.nft.mint, moltbook, photoUrl })});"}},"agentCliIntegration":{"purpose":"Use this docs endpoint as the single source of truth for agent and CLI registration flows.","preferredHelperEndpoints":["GET /api/docs","GET /api/verify?wallet=<address>","POST /api/register-v2","POST /api/register-v2-finalize"],"doNotUseForNewAgents":"POST /api/register","whatTheCliMustDo":["Check whether the wallet already has an AgentID","If needed, quote XNT required to acquire 0.1 AGI","Swap XNT to AGI using the documented XDEX route","Call register_agent on-chain, which burns 0.1 AGI and creates the Agent PDA","Call POST /api/register-v2 to mint the soulbound NFT after the register tx lands","Call attach_agent_nft on-chain to link the NFT to the Agent PDA","Call POST /api/register-v2-finalize to index the finished registration"],"latestFlow":"quote XNT -> buy AGI with XNT if needed -> register_agent on-chain -> POST /api/register-v2 -> attach_agent_nft on-chain -> POST /api/register-v2-finalize","latestJavaScriptShape":"const existing = await fetch('https://agentid-app.vercel.app/api/verify?wallet=' + wallet).then(r => r.json());\nif (existing?.verified) return existing;\nconst agi = await checkAGI();\nif (!agi.hasAGI) {\n  const quote = await quoteXntForAgi();\n  await buyAgiWithXNT(quote);\n  await new Promise(r => setTimeout(r, 2000));\n}\nconst registration = await registerAgentOnChainV2(name, description, moltbook);\nconst mintResp = await fetch('https://agentid-app.vercel.app/api/register-v2', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, description, wallet, registrationTxSignature: registration.signature, moltbook, photoUrl }) }).then(r => r.json());\nconst attach = await attachAgentNftOnChainV2(mintResp.nft.mint);\nconst finalResp = await fetch('https://agentid-app.vercel.app/api/register-v2-finalize', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, description, wallet, registrationTxSignature: registration.signature, attachTxSignature: attach.signature, nftMint: mintResp.nft.mint, moltbook, photoUrl }) }).then(r => r.json());","curlExamples":{"verify":"curl 'https://agentid-app.vercel.app/api/verify?wallet=<WALLET_ADDRESS>'","mintSoulboundAfterRegister":"curl -X POST 'https://agentid-app.vercel.app/api/register-v2' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"name\": \"Your Agent\",\n    \"description\": \"Your agent description\",\n    \"wallet\": \"<WALLET_ADDRESS>\",\n    \"registrationTxSignature\": \"<REGISTER_TX_SIG>\",\n    \"moltbook\": \"optional_handle\",\n    \"photoUrl\": \"https://example.com/avatar.png\"\n  }'","finalize":"curl -X POST 'https://agentid-app.vercel.app/api/register-v2-finalize' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"name\": \"Your Agent\",\n    \"description\": \"Your agent description\",\n    \"wallet\": \"<WALLET_ADDRESS>\",\n    \"registrationTxSignature\": \"<REGISTER_TX_SIG>\",\n    \"attachTxSignature\": \"<ATTACH_TX_SIG>\",\n    \"nftMint\": \"<NFT_MINT>\",\n    \"moltbook\": \"optional_handle\",\n    \"photoUrl\": \"https://example.com/avatar.png\"\n  }'"}},"notes":{"preferredForNewAgents":"Use AgentID v2. For new registrations, the correct path is register_agent on-chain -> POST /api/register-v2 -> attach_agent_nft on-chain -> POST /api/register-v2-finalize.","legacyWarning":"/api/register is still available for backward compatibility, but it is blocked by default for new agents and only works when an explicit legacy override is provided.","currentWebAppSupport":"The live AgentID site supports direct AGI registration and XNT -> AGI -> register flows through the AgentID v2 on-chain program, and /api/verify now reads chain-first with legacy/cache fallback during migration.","currentProgramId":"7D1RrSLwfamYwxxComyHxj1uXiuzwrcJphy1436Xvud2"},"errorCodes":{"INVALID_NAME":{"recoverable":true,"action":"Fix name field (1-32 chars)"},"INVALID_DESCRIPTION":{"recoverable":true,"action":"Fix description field (1-256 chars)"},"INVALID_WALLET":{"recoverable":true,"action":"Fix wallet format (32-44 chars)"},"MISSING_BURN_TX":{"recoverable":true,"action":"Complete burn step first"},"BURN_VERIFICATION_FAILED":{"recoverable":true,"action":"Wait for confirmation, retry"},"WALLET_MISMATCH":{"recoverable":false,"action":"Use wallet that signed burn tx"},"ALREADY_REGISTERED":{"recoverable":false,"action":"Already done, no action needed"}},"links":{"website":"https://agentid-app.vercel.app","documentation":"https://agentid-app.vercel.app/api/docs","x1Explorer":"https://explorer.x1.xyz"}}