{"version":1,"generatedAt":"2026-09-22T10:26:31.072Z","baseUrl":"https://markets-staging.capacitr.xyz","registryUrl":"https://markets-staging.capacitr.xyz/api/x402/routes","limits":{"challengesPerWindow":{"limit":120,"windowSeconds":60}},"routes":[{"kind":"signals_submit","method":"POST","path":"/api/x402/signals","url":"https://markets-staging.capacitr.xyz/api/x402/signals","title":"Submit a signal","description":"Turn a URL, a social post, an article, or a free-text market question into the Feed Card the Capacitr app renders for it: the markets it moves and the ranked trades across Polymarket, Hyperliquid and Robinhood Chain, each with a live quote and, for a dated source, its price at signal. Ranks and confidences are model-derived and follow the markets, so the same input can rank differently over time.","body":{"input":"string, REQUIRED. A URL, a post, or a question. `url` and `query` are accepted aliases for the same field; if more than one is sent, `input` wins, then `url`, then `query`. Sent as JSON in the request body.","mode":"string, optional, one of \"discover\" | \"hedge\". Default \"discover\", which ranks trade ideas; \"hedge\" looks for offsetting positions. Any other value is read as \"discover\"."},"response":{"recommendedTrades":"The ranked trades as one list, best first (bestTrade is the first entry; otherTrades are the rest). Each carries marketType (bet | trade), marketSource, marketId, marketTitle, suggestedDirection, confidence, recommendationRank, recommendationReason, quoteSnapshot (a live quote for the market at response time), and matchedAt. signalPrice — the recommended side's price at the source's publication time — is present only when the source has a publication time (a post, an article) and the lookup succeeded; a free-text question has no publication time, so its trades carry no signalPrice. Empty, with bestTrade null, when nothing tradeable was found.","title / subtitle / narratives":"What the source said and why each trade follows from it. narratives are the theses, each linked to the trades it supports.","categories / tags / publishedAt / url / sourceLabel":"The story's own metadata, as the app shows it.","payment":"What this call was charged: protocol (x402 | mpp), method (base | tempo), chain_id, currency, currency_address, amount, payer."},"enabled":true,"prices":[{"protocol":"x402","label":"x402","challenge":{"header":"PAYMENT-REQUIRED"},"credential":{"header":"PAYMENT-SIGNATURE"},"receipt":{"header":"PAYMENT-RESPONSE"},"method":"base","chainId":84532,"chain":"Base Sepolia (testnet)","token":{"address":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","symbol":"USDC","decimals":6},"amount":"0.2","enabled":true},{"protocol":"mpp","label":"MPP","challenge":{"header":"WWW-Authenticate","scheme":"Payment"},"credential":{"header":"Authorization","scheme":"Payment"},"receipt":{"header":"Payment-Receipt"},"method":"tempo","chainId":42431,"chain":"Tempo Moderato (testnet)","token":{"address":"0x20c0000000000000000000000000000000000000","symbol":"pathUSD","decimals":6},"amount":"0.2","enabled":true}],"limits":{"paidCallsPerPayer":{"limit":3,"windowSeconds":300},"maxRunSeconds":300}},{"kind":"signals_feed","method":"GET","path":"/api/x402/signals","url":"https://markets-staging.capacitr.xyz/api/x402/signals","title":"Read the latest signals","description":"The Signals Capacitr has already produced from its own monitored sources — each one the same complete Feed Card the submit route returns, with its narratives, its ranked trades across Polymarket and Hyperliquid, and a LIVE quote for every market fetched at response time. One payment returns one page; pass the returned cursor back for the next. An optional keyword filter narrows the page to a topic without changing the ordering, which is always newest first.","body":{"q":"string, optional, up to 120 characters. A keyword filter — a ticker (\"btc\"), a category (\"politics\"), or free text (\"electoral elections\"). Matched against the markets each Signal is matched to, the Signal's categories, and its headline and summary. Omit it for the latest Signals overall. Sent in the query string, like every parameter on this route.","limit":"integer, optional, 1 to 10. Signals per page. Default 10, which is also the maximum; a higher number is clamped to it, and a non-numeric one is a free 400.","cursor":"string, optional. The `nextCursor` from a previous response, opaque — pass it back unchanged. Omit it for the first page; one that did not come from a response is a free 400.","venues":"string, optional, comma-separated. The only value that changes anything is \"agg\": it adds aggregated-venue markets to the page. Anything else is ignored. Omit it for Polymarket and Hyperliquid only."},"response":{"signals":"The page, newest first. Each entry is a complete Feed Card — trendingItemId, title, subtitle, categories, tags, publishedAt, source metadata, narratives, bestTrade and otherTrades — plus `recommendedTrades`, the card's trades as one ranked list, best first. Every trade carries a live `quoteSnapshot` fetched at response time, and `signalPrice` where the source has a publication time.","nextCursor":"Pass back as `cursor` to buy the next page. `null` means the feed is exhausted; an empty `signals` array with a non-null cursor cannot happen.","payment":"What this call was charged: protocol (x402 | mpp), method (base | tempo), chain_id, currency, currency_address, amount, payer."},"enabled":true,"prices":[{"protocol":"x402","label":"x402","challenge":{"header":"PAYMENT-REQUIRED"},"credential":{"header":"PAYMENT-SIGNATURE"},"receipt":{"header":"PAYMENT-RESPONSE"},"method":"base","chainId":84532,"chain":"Base Sepolia (testnet)","token":{"address":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","symbol":"USDC","decimals":6},"amount":"0.1","enabled":true},{"protocol":"mpp","label":"MPP","challenge":{"header":"WWW-Authenticate","scheme":"Payment"},"credential":{"header":"Authorization","scheme":"Payment"},"receipt":{"header":"Payment-Receipt"},"method":"tempo","chainId":42431,"chain":"Tempo Moderato (testnet)","token":{"address":"0x20c0000000000000000000000000000000000000","symbol":"pathUSD","decimals":6},"amount":"0.1","enabled":true}],"limits":{"paidCallsPerPayer":{"limit":60,"windowSeconds":60},"maxRunSeconds":30}},{"kind":"market_narratives","method":"GET","path":"/api/x402/markets/narratives","url":"https://markets-staging.capacitr.xyz/api/x402/markets/narratives","title":"Read one market's narratives","description":"Every Narrative Capacitr has linked to one market — a Hyperliquid perp, a Robinhood Chain stock or a Polymarket market — newest first: what each source argued, which way it points, and the quote it came from. The same page the Capacitr app shows on that market's detail screen. One payment returns one page; pass the returned cursor back for the next.","body":{"marketType":"string, REQUIRED, one of \"trade\" | \"bet\". It must agree with marketSource — the venue decides the type, so only three pairs exist: trade+hyperliquid, trade+robinhood, bet+polymarket. Any other pairing is a free 400. Sent in the query string, like every parameter on this route.","marketSource":"string, REQUIRED, one of \"hyperliquid\" (perps, marketType trade) | \"robinhood\" (Robinhood Chain stock tokens, trade) | \"polymarket\" (prediction markets, bet). Capacitr's other two venues, \"agg\" and \"basestocks\", are not served here — the app shows no narratives on their detail screens either — and are a free 400.","marketId":"string, REQUIRED, 1 to 256 characters. The market's id on its venue: the coin for Hyperliquid (\"BTC\"), the 20-byte token contract address for Robinhood Chain (\"0x…\", case-insensitive), the conditionId for Polymarket (\"0x…\") — the marketId a Signal's trades carry. An id of the wrong shape for its venue is a free 400; a well-formed id for a market that does not exist cannot be told apart before the run, so it returns an empty page and the payment is refunded.","facet":"string, optional, default \"all\". A facet id from the response's own `facets`: \"direction:bullish\" | \"direction:bearish\" | \"direction:neutral\" on a perp or stock, \"direction:yes\" | \"direction:no\" or an outcome id on a Polymarket market. One this market has none of returns an empty page (refunded), not an error.","limit":"integer, optional, 10 to 15. Narratives per page. Default 10; anything outside the range is a free 400 rather than a clamp.","cursor":"string, optional. The `nextCursor` from a previous response, opaque — pass it back unchanged for the next page. One that did not come from a response is a free 400.","newerThan":"string, optional. A `firstCursor` from an earlier response, opaque: the page then carries only narratives published since it, and `newerResultsAvailable` says whether any exist. How to poll one market without re-buying the page you already have.","includeSignalId":"string, optional, one of \"1\" | \"0\" | \"true\" | \"false\". \"1\" or \"true\" adds `signalId` to each narrative — the Signal it came from, which `GET /api/x402/signals` returns as `trendingItemId`. Any other value is a free 400."},"response":{"narratives":"The page, newest first. Each carries id, title, mode, direction (bullish | bearish | neutral), subject, rationale, sourceExcerpt, source (kind, label, type, author), publishedAt, sourceDestination (the original post or article URL), linkedMarket (marketType, marketSource, marketId, suggestedDirection, selectedOutcome), and signalId when asked for.","facets":"Narrative counts for the whole market by direction: id, label, count — counted over the market, not the page.","nextCursor":"Pass back as `cursor` to buy the next page. `null` means there are no older narratives.","firstCursor / newerResultsAvailable":"The page's own newest position, and whether anything newer than the `newerThan` you sent exists. Send firstCursor back as `newerThan` to ask only for what has landed since.","payment":"What this call was charged: protocol (x402 | mpp), method (base | tempo), chain_id, currency, currency_address, amount, payer."},"enabled":true,"prices":[{"protocol":"x402","label":"x402","challenge":{"header":"PAYMENT-REQUIRED"},"credential":{"header":"PAYMENT-SIGNATURE"},"receipt":{"header":"PAYMENT-RESPONSE"},"method":"base","chainId":84532,"chain":"Base Sepolia (testnet)","token":{"address":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","symbol":"USDC","decimals":6},"amount":"0.05","enabled":true},{"protocol":"mpp","label":"MPP","challenge":{"header":"WWW-Authenticate","scheme":"Payment"},"credential":{"header":"Authorization","scheme":"Payment"},"receipt":{"header":"Payment-Receipt"},"method":"tempo","chainId":42431,"chain":"Tempo Moderato (testnet)","token":{"address":"0x20c0000000000000000000000000000000000000","symbol":"pathUSD","decimals":6},"amount":"0.05","enabled":true}],"limits":{"paidCallsPerPayer":{"limit":60,"windowSeconds":60},"maxRunSeconds":30}}],"prompt":"Use Capacitr's paid API for market signals: SUBMIT a URL, post, article or question to have it analysed into a Feed Card of matched markets and ranked trades, or READ the latest Signals Capacitr has already produced. Both return the same card shape, each trade carrying a live quote and, for a dated source, its price at signal time.\n\nReading is the cheaper door: one payment returns one page of Signals plus a `nextCursor`; pass that cursor back and pay again for the next page. Add `?q=` to narrow a page to a ticker, a category, or free text — ordering stays newest-first either way.\n\nFor one market, READ its Narratives: every thesis Capacitr has linked to that Hyperliquid perp, Robinhood Chain stock or Polymarket market, with direction, rationale and source. Same one-payment-per-page cursor.\n\nPOST https://markets-staging.capacitr.xyz/api/x402/signals — Submit a signal\nGET https://markets-staging.capacitr.xyz/api/x402/signals — Read the latest signals\nGET https://markets-staging.capacitr.xyz/api/x402/markets/narratives — Read one market's narratives\n\nRead GET https://markets-staging.capacitr.xyz/api/x402/routes for the current request fields, prices, payment rails, limits, and the response shape. The endpoint's 402 challenge carries the exact payment requirements.\n\nBefore any payment, collect from the user the input to analyze and a maximum spend per call. Then show the payment options the 402 challenge returns — currently USDC on Base Sepolia (testnet) over x402; pathUSD on Tempo Moderato (testnet) over MPP — ask the user which one to pay with, and wait for the answer. Use only an option returned by the challenge; never choose a chain automatically.\n\nFor every rail: validate the challenge's chain, token, recipient, and amount against the user's limit before signing, then verify the settlement receipt and confirm the on-chain transfer. Tempo may add a small network fee in pathUSD on top of the price unless the challenge marks the fee as sponsored, so check the transfer to the recipient against the price rather than the wallet's balance change.\n\nFollow the official guide or SDK for the chosen rail:\n- x402 on Base (Base Sepolia (testnet), USDC): https://docs.base.org/build-on-base/accept-payments/call-a-paid-service — install @x402/fetch and @x402/evm (the docs' @base-org/x402 name is not on npm). Register ExactEvmScheme with a viem account from the user's key, wrap fetch with wrapFetchWithPayment, and use onBeforePaymentCreation as the spend-limit gate.\n- MPP on Tempo (Tempo Moderato (testnet), pathUSD): https://mpp.dev/quickstart/agent — with a user-supplied private key use the mppx client SDK: Mppx.create({ methods: [tempo({ account, expectedChainId: 42431 })], polyfill: false }). Use the Tempo CLI skill at https://tempo.xyz/SKILL.md only for an interactive browser login. MPP is accepted on Tempo only; the Base rail is x402.\n\nAfter a network failure present the same credential again: it is never charged twice."}