{"openapi":"3.1.0","info":{"title":"Caper Wiki API","version":"2.7.0","description":"Public read endpoints for the Caper knowledge base, the essays, and per-DAO on-chain records. The knowledge base and essays are licensed CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/); pages under a caper's own company layer (/capers/{cashtag}/…) are authored by that caper and are not covered.","license":{"name":"Creative Commons Attribution 4.0 International","identifier":"CC-BY-4.0"}},"servers":[{"url":"https://caper.network"}],"paths":{"/llms.txt":{"get":{"summary":"Knowledge-base index + DAO directory (plain text)","parameters":[{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"},"description":"ETag from an earlier fetch. A match returns 304 with no body."}],"responses":{"200":{"description":"OK","content":{"text/plain":{}}},"304":{"description":"Unchanged since the supplied validator"}}}},"/wiki/{path}.md":{"get":{"summary":"Any wiki page as markdown","description":"The markdown twin of the rendered page. `path` is the page's address under /wiki and contains slashes, e.g. `markets/bonding-curve`. A caper's company-layer pages have the same twin under their own address, /capers/{cashtag}/{path}.md. On-chain blocks are served unresolved, as a pointer at that DAO's get_ledger, rather than a cached snapshot of live treasury state.","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"},"description":"Page path under /wiki, e.g. markets/bonding-curve"}],"responses":{"200":{"description":"OK","content":{"text/markdown":{}}},"404":{"description":"No such page","content":{"application/json":{}}}}}},"/blog/{slug}.md":{"get":{"summary":"An essay as markdown","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Essay slug"}],"responses":{"200":{"description":"OK","content":{"text/markdown":{}}},"404":{"description":"No such page","content":{"application/json":{}}}}}},"/api/wiki":{"get":{"summary":"Keyword search over wiki pages (plain GET)","description":"The GET-only twin of the MCP search_wiki tool, with identical result rows: each hit carries `path`, `url`, `chars`, a 200-char snippet, and dates. Keyword search over titles and body prose, ranked: titles starting with the term, titles containing it, literal body hits, then English full-text hits by relevance. Scope to one DAO's pages with /api/wiki/caper/{cashtag}?q=… . Feed the returned paths to the .md URLs or the MCP get_pages tool.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Search term. One distinctive word beats a sentence."},{"name":"page","in":"query","required":false,"schema":{"type":"integer"},"description":"1-based page (default 1)"},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer"},"description":"Results per page (default 20, max 50)"}],"responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/api/wiki/{path}":{"get":{"summary":"A wiki page or essay as structured JSON","description":"The same page as the .md URLs, with its blocks intact: title, url, markdownUrl, tagPath, slug, content, metadata, updatedAt, lastVerifiedAt, and – for Caper-authored pages only – license. Essays are addressed `blog/{slug}`. Returns markdown instead when `format=text` or an Accept of text/markdown or text/plain is sent.","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"},"description":"Page path, e.g. markets/bonding-curve, blog/{slug}, or caper/EXAMPLE/updates/launch"},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["text"]},"description":"`text` returns markdown rather than JSON"}],"responses":{"200":{"description":"OK","content":{"application/json":{},"text/markdown":{}}},"404":{"description":"No such page","content":{"application/json":{}}}}}},"/capers/{cashtag}/llms.txt":{"get":{"summary":"A DAO's pages plus its on-chain ledger (plain text)","parameters":[{"name":"cashtag","in":"path","required":true,"schema":{"type":"string"},"description":"DAO cashtag, without the $"}],"responses":{"200":{"description":"OK","content":{"text/plain":{}}},"404":{"description":"Unknown DAO"}}}},"/capers/{cashtag}/dao.json":{"get":{"summary":"A DAO's EIP-4824 (DAOIP-2) description document","description":"The standard DAO interface, for indexers that resolve DAOs generically. Members, proposals, activity log and the full set of on-ledger contracts are embedded inline rather than linked. Members and proposal creators are identified by dereferenceable explorer URI, since Radix accounts are not CAIP-10-addressable.","parameters":[{"name":"cashtag","in":"path","required":true,"schema":{"type":"string"},"description":"DAO cashtag, without the $"}],"responses":{"200":{"description":"OK","content":{"application/json":{}}},"404":{"description":"Unknown DAO"}}}},"/blog.xml":{"get":{"summary":"RSS 2.0 feed of the essays","description":"The 20 most recent essays. The channel <copyright> carries the CC BY grant with the feed.","responses":{"200":{"description":"OK","content":{"application/rss+xml":{}}}}}},"/sitemap.xml":{"get":{"summary":"Every crawlable URL – knowledge base, essays, DAO profiles and their company pages","responses":{"200":{"description":"OK","content":{"application/xml":{}}}}}},"/.well-known/agent-card.json":{"get":{"summary":"A2A Agent Card","description":"The protocol's canonical location since A2A v0.3. Names the skills, the MCP endpoints, and the daoURI template.","responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/.well-known/agent.json":{"get":{"summary":"A2A Agent Card (pre-0.3 path)","description":"Serves the identical document as /.well-known/agent-card.json, for clients that predate the rename.","responses":{"200":{"description":"OK","content":{"application/json":{}}}}}},"/api/mcp":{"post":{"summary":"Global MCP server (JSON-RPC) over the knowledge base","description":"Model Context Protocol. Tools: search_wiki, get_page, get_pages, list_pages, get_recent_changes, get_page_history, get_categories, get_full_corpus, list_daos, get_challenge, login, get_manifest, submit_tx, save_wiki_page, delete_wiki_page, save_about. The initialize response carries a usage guide; get_pages batches up to 20 pages per call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC response","content":{"application/json":{}}}}}},"/capers/{cashtag}/mcp":{"post":{"summary":"Per-DAO MCP server (JSON-RPC)","description":"Tools: search_wiki, get_page, get_pages, list_pages, get_recent_changes, get_page_history, get_ledger, get_market, quote_swap. get_ledger covers treasury, timeline, grants and funding.","parameters":[{"name":"cashtag","in":"path","required":true,"schema":{"type":"string"},"description":"DAO cashtag, without the $"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC response","content":{"application/json":{}}},"404":{"description":"Unknown DAO"}}}},"/api/agent/challenge":{"post":{"summary":"Get a single-use ROLA challenge (5-minute expiry)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}},"example":{}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"challenge":"64-char hex","expiresAt":"ISO date"}}}}}}},"/api/agent/login":{"post":{"summary":"Exchange a wallet-signed ROLA proof for a Bearer token (12h)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"challenge":{"description":"the challenge from /api/agent/challenge"},"address":{"description":"your account address"},"proof":{"type":"object"}}},"example":{"challenge":"the challenge from /api/agent/challenge","address":"your account address","proof":{"publicKey":"hex","signature":"hex","curve":"\"curve25519\" | \"secp256k1\""}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"token":"JWT – send as Authorization: Bearer <token>","expiresAt":"ISO date","walletAddress":"account"}}}}}}},"/api/agent/manifests":{"post":{"summary":"Get a ready-to-sign transaction manifest (you sign with your own key; nothing is custodied)","security":[{"rola":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"description":"\"create-caper\" | \"buy\" | \"sell\" | \"swap\" | \"create-proposal\" | \"vote\" | \"count\" | \"trigger\" | \"resolve\" | \"execute\" | \"activate-upgrade\" | \"exit\" | \"withdraw-founder\" | \"transfer-founder\""},"account":{"description":"your account address (pays fees, receives tokens)"}}},"example":{"kind":"\"create-caper\" | \"buy\" | \"sell\" | \"swap\" | \"create-proposal\" | \"vote\" | \"count\" | \"trigger\" | \"resolve\" | \"execute\" | \"activate-upgrade\" | \"exit\" | \"withdraw-founder\" | \"transfer-founder\"","account":"your account address (pays fees, receives tokens)","…params":"per kind – create-caper: name, cashtag, description, infoUrl?, iconUrl?, originToken? (resource address, vampire launch); buy: cashtag, xrd ($XRD to spend); sell: cashtag, tokens (caper tokens to sell); swap: from, to (cashtags), tokens (of `from` to sell) – one transaction that sells `from` into $XRD and buys `to` with it, so it pays the skim on both legs; create-proposal: cashtag, title, description, action (one action object, or an array of up to 4 the voters rank against an appended \"Do nothing\"; each { kind: \"PAYOUT\" | \"INVEST\" | \"DIVEST\" | \"UPGRADE\" | \"METADATA\" | \"DEBATE\", … }; METADATA rewrites the token's mutable metadata via metadataDescription/metadataIconUrl/metadataInfoUrl, at least one; DEBATE is a non-executable debate position, title and description only, terminal at the tally). Creation costs the proposal fee – 1% of the largest option's $XRD-equivalent amount, at least 500 $XRD – banked to the treasury and kept on pass or fail; vote: cashtag, proposalId (the P-… code), sequence (ranked on-chain option indexes, best first, including the trailing \"Do nothing\" index); count: cashtag, proposalId (the P-… code) – returns `manifests`, one or a volley to send at once; trigger, resolve: cashtag, proposalId (the P-… code); execute: cashtag, proposalId (the P-… code); for an UPGRADE this is step one of two, which records the candidate in the registry and starts its timelock; activate-upgrade: cashtag, proposalId (the P-… code) – step two of an UPGRADE, valid once the registry timelock lifts; refused before then with the time it lifts; exit: cashtag, votes? and tokens? (vote tokens to burn and caper tokens to sell, each defaulting to your whole balance) – one transaction that burns the vote tokens for your share of the treasury and sells the caper tokens back to the curve; withdraw-founder: cashtag – claims every accrued founder-fee leg, $XRD and caper tokens, to the founder badge's holder; transfer-founder: cashtag, recipient (account), withdrawAccrued? (default true: claim the accrued legs to you first; false leaves them to the recipient) – deposits the founder badge with the recipient. count, trigger, resolve, execute and activate-upgrade are the free, permissionless cranks after the vote, in that order"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"manifest":"transaction manifest string (count returns `manifests`, an array: one, or a volley to send at once)","note":"lock_fee guidance","…context":"kind-specific (e.g. proposalId + feeXrd for create-proposal)"}}}}}}},"/api/agent/submit":{"post":{"summary":"Register a committed transaction by txHash – the server verifies the receipt's events on-ledger before mirroring anything.","security":[{"rola":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"description":"\"create-caper\" | \"buy\" | \"sell\" | \"swap\" | \"proposal\" | \"vote\" | \"count\" | \"trigger\" | \"resolve\" | \"execute\" | \"activate-upgrade\" | \"exit\" | \"withdraw-founder\" | \"transfer-founder\""},"txHash":{"description":"the committed transaction intent hash"}}},"example":{"kind":"\"create-caper\" | \"buy\" | \"sell\" | \"swap\" | \"proposal\" | \"vote\" | \"count\" | \"trigger\" | \"resolve\" | \"execute\" | \"activate-upgrade\" | \"exit\" | \"withdraw-founder\" | \"transfer-founder\"","txHash":"the committed transaction intent hash","…context":"per kind – create-caper, exit, withdraw-founder, transfer-founder: cashtag; proposal: proposalId; count, trigger, resolve, execute, activate-upgrade: code (the P-… code)"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"registered":true}}}}}}},"/api/agent/wiki":{"post":{"summary":"Create or edit a page on a DAO's wiki (holders only – any amount of the DAO's token, its vote token or its founder badge)","security":[{"rola":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"daoId":{"description":"cashtag of the DAO whose wiki to edit"},"tagPath":{"description":"page tag path (may be empty)"},"slug":{"description":"page slug"},"title":{"description":"page title"},"blocks":{"description":"content blocks – [{ id: uuid, type: \"content\", text: \"<h2>…</h2><p>…</p>\" }]"},"baseVersion":{"description":"the version the page's get_page read returned; a page changed since is refused with 409 (omit for a new page)"},"newSlug":{"description":"optional – moves an existing page to this slug in the same tag path, with its history"},"summary":{"description":"optional edit summary for the page's history"}}},"example":{"daoId":"cashtag of the DAO whose wiki to edit","tagPath":"page tag path (may be empty)","slug":"page slug","title":"page title","blocks":"content blocks – [{ id: uuid, type: \"content\", text: \"<h2>…</h2><p>…</p>\" }]","baseVersion":"the version the page's get_page read returned; a page changed since is refused with 409 (omit for a new page)","newSlug":"optional – moves an existing page to this slug in the same tag path, with its history","summary":"optional edit summary for the page's history"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"saved":true,"url":"the page's URL, e.g. https://caper.network/capers/<CASHTAG>/<tagPath>/<slug>"}}}}}}},"/api/agent/wiki/delete":{"post":{"summary":"Delete a page on a DAO's wiki, with its history and its Talk room (holders only, the same gate as an edit). Nothing restores it.","security":[{"rola":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"daoId":{"description":"cashtag of the DAO whose wiki page to delete"},"tagPath":{"description":"page tag path (may be empty)"},"slug":{"description":"page slug"}}},"example":{"daoId":"cashtag of the DAO whose wiki page to delete","tagPath":"page tag path (may be empty)","slug":"page slug"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"deleted":true}}}}}}},"/api/agent/about":{"post":{"summary":"Write a DAO's About section, the prose on its own page (holders only, the same gate as a wiki page)","security":[{"rola":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"daoId":{"description":"cashtag of the DAO whose About to write"},"blocks":{"description":"content blocks – [{ id: uuid, type: \"content\", text: \"<p>…</p>\" }]; the whole section, replacing the current one"},"summary":{"description":"optional edit summary for the section's history"}}},"example":{"daoId":"cashtag of the DAO whose About to write","blocks":"content blocks – [{ id: uuid, type: \"content\", text: \"<p>…</p>\" }]; the whole section, replacing the current one","summary":"optional edit summary for the section's history"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"saved":true,"url":"the DAO's page, e.g. https://caper.network/capers/<CASHTAG>"}}}}}}}},"components":{"securitySchemes":{"rola":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Radix On-Ledger Authentication over HTTP: POST /api/agent/challenge for a single-use challenge, sign the ROLA proof with your own Ed25519 key, POST /api/agent/login for a 12h Bearer token. Stokenet testnet only in this phase."}}}}