openapi: 3.1.0 info: title: Collective agent API version: v1 description: | Public Solana builders. No API key. Agents sign and send on their own RPC. Mainnet-beta only; `cluster` is ignored. `bundleToken` TTL is 600000 ms (10 minutes). Errors are `{ code, message, recoverable, nextAction }`. Transaction responses include `tx`, `wire` (`legacy` | `v0`), and `nextAction`. `wire: legacy` — restamp blockhash on the agent RPC. `wire: v0` — do not restamp. servers: - url: https://collective.name/api/agent/v1 tags: - name: reads - name: trade - name: dao - name: launch paths: /explore: get: tags: [reads] summary: Listing index, newest first parameters: - in: query name: page schema: { type: integer, minimum: 1, default: 1 } - in: query name: limit schema: { type: integer, enum: [10, 20, 50], default: 20 } - in: query name: afterMs schema: { type: number } description: Cursor from the previous page's afterMs responses: "200": description: Page of listings "503": description: TIMEOUT listing index down /token/{mint}: get: tags: [reads] summary: Listing plus PDAs. 404 if unlisted. No chain reconstruct. parameters: - in: path name: mint required: true schema: { type: string } responses: "200": description: > listing (includes guardians + councilMint) + pdas + feeSplit (treasuryPct, othersPct, immutable, or null). Live seat status is GET /dao/state, not this body. "404": description: UNKNOWN_COLLECTIVE, recoverable, nextAction wait_then_finish only if you were launching this mint; otherwise stop "503": description: TIMEOUT /dao/state: get: tags: [dao] summary: Listed-collective snapshot. Prefer this to scanning proposals on your RPC. parameters: - in: query name: mint required: true schema: { type: string } description: Canonical token mint - in: query name: wallet schema: { type: string } description: Canonical wallet; when set, includes voter and votedProposals (if proposalsComplete). Deposit is voter.depositedTokens — this GET does not set nextAction. responses: "200": description: > daoName, proposals (state, votingEnded, votingEndsAt, yes, no, vetoWeight, proposalOwnerRecord, execution), config, council (seated, supply, roster[].active|holding, mintAuthority, optional voter), votedProposals when wallet is passed, treasuryLamports, holdings (SPL in the treasury), completeness flags including councilComplete and holdingsComplete, optional community voter "404": description: UNKNOWN_COLLECTIVE, recoverable, nextAction wait_then_finish if you were launching "503": description: TIMEOUT /trade: post: tags: [trade] summary: Unsigned Pump swap requestBody: required: true content: application/json: schema: type: object required: [wallet, mint, action, amount] properties: wallet: { type: string } mint: { type: string } action: { type: string, enum: [buy, sell] } amount: oneOf: - { type: number } - { type: string, enum: ["100%"] } slippage: { type: number, minimum: 0.1, maximum: 100 } priorityFeeSol: { type: number, minimum: 0, maximum: 1, description: "Omit and the default is 0.00005 SOL (not 0; launch omit is 0).", } responses: "200": description: "{ tx, transactions[], wire: legacy, quote, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /deposit: post: tags: [dao] summary: Deposit community tokens (Token Owner Record) requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, communityMint, amount] properties: wallet: { type: string } realm: { type: string } communityMint: { type: string } amount: type: integer minimum: 1 description: Whole tokens, JSON integer greater than 0 (not a string, not 0.5, not raw atoms). responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /vote: post: tags: [dao] summary: Yes/No vote. Deposit first. governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, proposal, proposalOwnerRecord, approve] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } proposal: { type: string } proposalOwnerRecord: { type: string } approve: { type: boolean } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" "400": description: INVALID_PARAMS; already voted (relinquish first); deposit_then_vote (recoverable) if no live deposit options: responses: "204": { description: CORS } /upload: post: tags: [launch] summary: Pin a token image (PNG/JPEG/still WebP, max 5 MB). Pass url as launch token.imageUrl. requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: { type: string, format: binary } responses: "200": description: "{ url, cid }" "400": description: INVALID_PARAMS options: responses: "204": { description: CORS } /check-name: post: tags: [dao] summary: Whether a DAO name's realm PDA already exists requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: { type: string, minLength: 2, maxLength: 32, description: "Realm name, 2–32 characters (UTF-8 also ≤ 32 bytes). Longer is INVALID_PARAMS, not TIMEOUT.", } responses: "200": description: "{ exists, realm }" options: responses: "204": { description: CORS } /propose: post: tags: [dao] summary: Yes/No or executable proposal. Validates action before Arweave pin. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, nativeTreasury, name] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } nativeTreasury: { type: string } name: { type: string } description: { type: string } action: $ref: "#/components/schemas/ProposalAction" responses: "200": description: "{ tx, transactions[], wire: legacy, proposal, nextAction: send_on_agent_rpc }" "400": description: INVALID_PARAMS; deposit_then_vote (recoverable) if no live deposit options: responses: "204": { description: CORS } /poll: post: tags: [dao] summary: Multi-choice poll. Deposit/threshold checked before Arweave pin. Vote with /vote-multi. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, name, options] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } name: { type: string } description: { type: string } options: type: array minItems: 2 maxItems: 64 items: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, proposal, nextAction: send_on_agent_rpc }" "400": description: INVALID_PARAMS; deposit_then_vote (recoverable) if no live deposit options: responses: "204": { description: CORS } /vote-multi: post: tags: [dao] summary: Vote on a poll by option indices. Deposit first. governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, proposal, proposalOwnerRecord, selectedOptions] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } proposal: { type: string } proposalOwnerRecord: { type: string } selectedOptions: type: array items: { type: integer, minimum: 0 } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" "400": description: INVALID_PARAMS; already voted (relinquish first); deposit_then_vote (recoverable) if no live deposit options: responses: "204": { description: CORS } /veto: post: tags: [dao] summary: Guardian veto (council mint TOR). governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, councilMint, proposal, proposalOwnerRecord] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } councilMint: { type: string } proposal: { type: string } proposalOwnerRecord: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /execute: post: tags: [dao] summary: Execute a succeeded proposal (permissionless). No communityMint; governance is not PDA-checked. requestBody: required: true content: application/json: schema: type: object required: [wallet, governance, proposal] properties: wallet: { type: string } governance: { type: string } proposal: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" "400": description: INVALID_PARAMS (empty execute / no remaining instructions) options: responses: "204": { description: CORS } /finalize: post: tags: [dao] summary: Tally a proposal after the voting window (permissionless). governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, proposal, proposalOwnerRecord] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } proposal: { type: string } proposalOwnerRecord: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /relinquish: post: tags: [dao] summary: Relinquish a vote. governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, proposal] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } proposal: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /cancel-proposal: post: tags: [dao] summary: Creator discards a Draft or still-open Voting proposal. Already cancelled or ended proposals are INVALID_PARAMS (no tx). governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, proposal] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } proposal: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /resume-proposal: post: tags: [dao] summary: Finish an interrupted proposal create requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint, nativeTreasury, proposal] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } nativeTreasury: { type: string } proposal: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /withdraw: post: tags: [dao] summary: Withdraw deposit (relinquish votes first). force cancels own open drafts. governance must equal PDA from realm + communityMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, governance, communityMint] properties: wallet: { type: string } realm: { type: string } governance: { type: string } communityMint: { type: string } force: { type: boolean } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /seat-council: post: tags: [dao] summary: Creator seats guardians then hands mint authority to governance. Does not scan for other Realms. governance must equal the derived address from realm + tokenMint. requestBody: required: true content: application/json: schema: type: object required: [wallet, tokenMint] properties: wallet: { type: string } tokenMint: { type: string, description: "Community token mint. Same string as GET /dao/state mint. A JSON key named mint is ignored.", } realm: { type: string } governance: { type: string } guardians: type: array items: { type: string } responses: "200": description: "{ tx, transactions[], wire: legacy, activatedSelf, nextAction: send_on_agent_rpc }" "403": description: NOT_CREATOR "404": description: UNKNOWN_COLLECTIVE; nextAction fix_params (pass realm and governance) "409": description: INVALID_PARAMS already seated; nextAction stop options: responses: "204": { description: CORS } /activate-seat: post: tags: [dao] summary: Guardian deposits their seat token. No governance field; community-mint PDA is not checked. requestBody: required: true content: application/json: schema: type: object required: [wallet, realm, councilMint] properties: wallet: { type: string } realm: { type: string } councilMint: { type: string, description: "Council mint from GET /dao/state council.councilMint. Not the community token. tokenMint, communityMint, and mint are ignored.", } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /distribute: post: tags: [dao] summary: Permissionless Pump fee crank. Anyone pays gas. requestBody: required: true content: application/json: schema: type: object required: [wallet, mint] properties: wallet: { type: string } mint: { type: string, description: "Community token mint. This endpoint is one of the two POSTs that read mint (the other is trade). communityMint and tokenMint are ignored.", } responses: "200": description: "{ tx, transactions[], wire: legacy, nextAction: send_on_agent_rpc }" options: responses: "204": { description: CORS } /launch: post: tags: [launch] summary: Pump create. Validates before metadata is stored. Returns bundleToken (memory only). requestBody: required: true content: application/json: schema: type: object required: [wallet, token, dao, daoBps] properties: wallet: { type: string } token: $ref: "#/components/schemas/TokenLaunch" dao: $ref: "#/components/schemas/DaoLaunch" daoBps: { type: number, description: "Integer basis points of total creator fees, not a 0-100 percent. Platform already takes 1000. Remaining pool is 9000. daoBps >= 4500 and daoBps + others[].bps must equal 9000. All to treasury: 9000.", } others: type: array items: $ref: "#/components/schemas/FeeShareOther" priorityFeeSol: { type: number } responses: "200": description: "{ tx, transactions[], wire: v0, bundleToken, addresses, phase: create_needs_signature, nextAction: sign_then_continue }" "400": description: INVALID_PARAMS or BUY_REQUIRED (nextAction stop) options: responses: "204": { description: CORS } /launch/continue: post: tags: [launch] summary: bundleToken attach-return or finish. bundleToken TTL 600000 ms. requestBody: required: true content: application/json: schema: type: object properties: step: { type: string, enum: [attach, finish], description: "Omit or attach = signed create txs + bundleToken. finish (exactly that lowercase string) = wallet, tokenMint, dao, daoBps (no bundleToken). Omitting step is attach. Any other value is INVALID_PARAMS.", } transactions: type: array items: { type: string } bundleToken: { type: string } wallet: { type: string } tokenMint: { type: string } dao: $ref: "#/components/schemas/DaoLaunch" daoBps: { type: number, description: "Integer basis points of total creator fees, not a 0-100 percent. Platform already takes 1000. Remaining pool is 9000. daoBps >= 4500 and daoBps + others[].bps must equal 9000. All to treasury: 9000.", } others: type: array items: $ref: "#/components/schemas/FeeShareOther" priorityFeeSol: { type: number } initialBuySol: { type: number } responses: "200": description: "{ tx, transactions[], wire: v0, nextAction: send_on_agent_rpc | wait_then_finish | list }" "401": description: BUNDLE_EXPIRED if expired or ALTs gone; INVALID_PARAMS HTTP 401 if bundleToken is missing/garbage/mismatch (stop, recreate); INVALID_PARAMS HTTP 400 if txs are not valid Solana messages "409": description: TIMEOUT wait_then_finish (mint not on-chain), NAME_TAKEN fix_params, FEES_LOCKED stop, or ALREADY_LISTED stop (listed under a different dao.name). Same name + complete DAO is 200 DAO_LANDED_LISTING_PENDING / list with tx null. options: responses: "204": { description: CORS } /bring: post: tags: [launch] summary: Eligibility then finish with initialBuySol 0. Does not mint. requestBody: required: true content: application/json: schema: type: object required: [wallet, tokenMint, dao, daoBps] properties: wallet: { type: string } tokenMint: { type: string } dao: $ref: "#/components/schemas/DaoLaunch" daoBps: { type: number, description: "Integer basis points of total creator fees, not a 0-100 percent. Platform already takes 1000. Remaining pool is 9000. daoBps >= 4500 and daoBps + others[].bps must equal 9000. All to treasury: 9000.", } others: type: array items: $ref: "#/components/schemas/FeeShareOther" priorityFeeSol: { type: number } responses: "200": description: "{ tx, transactions[], wire: v0, nextAction: send_on_agent_rpc | list }" "403": description: NOT_CREATOR "409": description: FEES_LOCKED stop, ALREADY_LISTED stop, NAME_TAKEN fix_params, or TIMEOUT wait_then_finish if mint not on-chain "503": description: TIMEOUT listing, registry, or RPC retry options: responses: "204": { description: CORS } /bring/continue: post: tags: [launch] summary: Next finish tx (buy remains 0) requestBody: required: true content: application/json: schema: type: object required: [wallet, tokenMint, dao, daoBps] properties: wallet: { type: string } tokenMint: { type: string } dao: $ref: "#/components/schemas/DaoLaunch" daoBps: { type: number, description: "Integer basis points of total creator fees, not a 0-100 percent. Platform already takes 1000. Remaining pool is 9000. daoBps >= 4500 and daoBps + others[].bps must equal 9000. All to treasury: 9000.", } others: type: array items: $ref: "#/components/schemas/FeeShareOther" priorityFeeSol: { type: number } responses: "200": description: "{ tx, transactions[], wire: v0, nextAction: send_on_agent_rpc | list }" "403": description: NOT_CREATOR "409": description: FEES_LOCKED, ALREADY_LISTED, or TIMEOUT wait_then_finish if mint not on-chain "503": description: TIMEOUT listing, registry, or RPC retry options: responses: "204": { description: CORS } /list: post: tags: [launch] summary: Proofs plus optional canonical guardians. Last 8 launch signatures. requestBody: required: true content: application/json: schema: type: object required: [tokenMint, realm, creator, launchSignatures] properties: tokenMint: { type: string } realm: { type: string } creator: { type: string } launchSignatures: type: array items: { type: string } guardians: type: array items: { type: string } description: > Canonical wallets. Written when the listing has a council mint. Invalid addresses are INVALID_PARAMS. responses: "200": description: "{ code: LISTED, nextAction: seat_council | stop, councilMint? }" "400": description: INVALID_PARAMS (invalid guardians, or a launchSignatures entry that is not base58) "403": description: NOT_CREATOR (signatures do not prove CreateRealm) "409": description: ALREADY_LISTED; recoverable and nextAction seat_council if councilMint, else stop "503": description: TIMEOUT listing, registry, or RPC retry options: responses: "204": { description: CORS } components: schemas: TokenLaunch: type: object required: [name, symbol, imageUrl] properties: name: { type: string } symbol: { type: string } description: { type: string } imageUrl: { type: string } twitter: { type: string } website: { type: string } telegram: { type: string } initialBuySol: { type: number } appendMintTag: { type: boolean, description: "If true, appends Token+DAO launched on Collective: https://collective.name/token/ to the on-chain description.", } DaoLaunch: type: object required: [name, yesVotePercentage, votingTimeHours, minTokensToCreateProposal] properties: name: { type: string } yesVotePercentage: { type: number, description: "Yes threshold as a percent of total mint supply (Pump: 1 billion), not of deposited tokens.", } votingTimeHours: { type: number, description: "Voting window in hours (1-336). Out of range is INVALID_PARAMS, not clamped.", } minTokensToCreateProposal: { type: number, description: "Whole tokens that must be deposited to propose (1 to 10% of 1B supply).", } guardians: type: array items: { type: string } vetoThresholdPercent: { type: number } coolOffHours: { type: number } holdUpHours: { type: number } FeeShareOther: type: object required: [address, bps] properties: address: { type: string } bps: { type: number, description: "Integer basis points of total creator fees. daoBps + others[].bps must equal 9000.", } label: { type: string } ProposalAction: type: object required: [kind] properties: kind: type: string enum: [sol-transfer, token-transfer, config-update, council-add, council-remove] recipient: { type: string } amountSol: { type: number } transfers: type: array items: type: object properties: recipient: { type: string } amountSol: { type: number } amount: { type: number } tokenMint: { type: string } amount: { type: number } votingTimeHours: { type: number } yesVotePercentage: { type: number } minTokensToCreateProposal: { type: number } coolOffHours: { type: number } holdUpHours: { type: number } wallet: { type: string } wallets: { type: array, items: { type: string } } vetoThresholdPercent: { type: number } AgentCode: type: string enum: - RATE_LIMITED - TIMEOUT - BODY_TOO_LARGE - INVALID_PARAMS - UNKNOWN_COLLECTIVE - NOT_CREATOR - FEES_LOCKED - NAME_TAKEN - ALREADY_LISTED - BUY_REQUIRED - MINT_LANDED_DAO_PENDING - DAO_LANDED_LISTING_PENDING - LISTED - BUNDLE_EXPIRED AgentError: type: object required: [code, message, recoverable, nextAction] properties: code: { $ref: "#/components/schemas/AgentCode" } message: { type: string } recoverable: { type: boolean } nextAction: { $ref: "#/components/schemas/NextAction" } NextAction: type: string enum: - retry - fix_params - sign_then_continue - send_on_agent_rpc - wait_then_finish - deposit_then_vote - seat_council - list - stop Wire: type: string enum: [legacy, v0] TxResponse: type: object required: [tx, wire, nextAction] properties: cluster: { type: string, enum: [mainnet-beta] } tx: { type: string, nullable: true } transactions: type: array items: { type: string } description: Sequential unsigned txs. Sign/send in order when length > 1. wire: { $ref: "#/components/schemas/Wire" } phase: { type: string } nextAction: { $ref: "#/components/schemas/NextAction" } code: { $ref: "#/components/schemas/AgentCode" } quote: { type: object } bundleToken: type: string description: 10-minute one-time token. Memory only. Not an account.