关于 manifold
manifold 是面向 Manifold 预测市场 API 的技能,帮助开发者以程序方式查询市场、读取数据并执行交易和市场管理操作。
主要功能
- 01搜索与列出市场
- 02读取概率和持仓
- 03访问用户与投资组合数据
- 04创建和管理市场
- 05交易及管理流动性
适用场景
- 01构建市场发现工具
- 02分析市场概率与持仓
- 03通过 API 自动交易
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ outsharp/ shipp-skills --skill manifold安装后在 Claude Code 中输入/manifold确认已加载。
附带文件README.md
详细介绍
Manifold API
Manifold 是一个预测市场平台,用户可在此创建并交易有关现实世界事件的问题。平台结合使用游戏币(mana)和奖金现金,并采用自动做市商(CPMM)机制,提供丰富的 API 以供程序化访问。
请 经常 查看此技能和官方文档,了解更新。API 仍处于 alpha 阶段,可能会在不另行通知的情况下变更。
社区: 加入 Manifold Discord,提出问题、报告错误并分享你的创作。
源代码: Manifold 是开源的。类型定义位于 common/src/api/schema.ts。
核心概念(术语表)
| 术语 | 定义 |
|---|---|
| 市场(合约) | 一个可交易的问题。在代码库中称为“合约”,在 API 中称为“市场”。有一个结果类型(BINARY、MULTIPLE_CHOICE、PSEUDO_NUMERIC、BOUNTIED_QUESTION、POLL)。 |
| Mana(M$) | 大多数市场使用的游戏币。不能兑换成真实货币提现。 |
| 奖金现金(CASH) | 可用于特定市场的真实货币。可以提现。在市场上通过 token: "CASH" 标识。 |
| 关联合约 | 市场对应的 mana 或奖金现金合约。通过 siblingContractId 在两者之间切换。 |
| 主题(组) | 为市场分类而添加的标签。在代码库和 API 中称为“组”。 |
| CPMM | 恒定乘积做市商。用于二元(cpmm-1)和多答案(cpmm-multi-1)市场的自动做市商。 |
| DPM | 动态彩池市场(Dynamic Parimutuel Market)——一种用于较早期自由回答市场的旧机制(dpm-2)。 |
| 概率 | 一个介于 0 和 1 之间的数字,表示市场当前隐含的 YES 概率。 |
| 资金池 | 为做市商提供支撑的份额流动性池。对于 CPMM 市场,会显示 YES 和 NO 份额数量。 |
| 流动性 | 存入 AMM 资金池的 mana。流动性越高,每笔交易对价格的影响越小。 |
| 下注 | 在市场上的交易。可以是市价单,也可以是限价单(指定 limitProb 时)。 |
| 限价单 | 仅在指定概率价格或更优价格下执行的下注。在成交、取消或过期前保持开放。 |
| 份额 | 一个仓位的单位。获胜的 YES 份额每份支付 M$1;失败的份额每份支付 M$0。 |
| 结算 | 市场的最终结果:YES、NO、MKT(概率)或 CANCEL。 |
| 答案 | MULTIPLE_CHOICE 或 FREE_RESPONSE 市场中的一个可能结果。每个答案都有各自的概率。 |
| 悬赏 | 一种 BOUNTIED_QUESTION 市场,创建者会向最佳评论或答案发放 mana 奖励。 |
| 投票 | 一种不可交易的市场类型,用户只需对选项投票。 |
基础 URL
| 环境 | REST API | WebSocket |
|---|---|---|
| 生产环境 | https://api.manifold.markets | wss://api.manifold.markets/ws |
| 开发环境 | https://api.dev.manifold.markets | wss://api.dev.manifold.markets/ws |
重要: API 最近已从
https://manifold.markets/api迁移至https://api.manifold.markets。旧域名将在未来停用。请始终使用新域名。
所有 REST 端点均以 /v0/ 为前缀。
文档与参考资料
身份验证
部分端点是公开的(无需身份验证)。写入端点和针对用户的读取操作需要通过 API 密钥进行身份验证。
生成 API 密钥
- 登录 Manifold。
- 前往你的用户个人资料并点击“edit”。
- 向下滚动到页面底部的 API 密钥字段。
- 点击“refresh”按钮生成新密钥。
- 复制并妥善保存密钥。再次点击“refresh”会使旧密钥失效,并生成新密钥。
使用 API 密钥
在 Authorization 标头中包含密钥:
Authorization: Key {your_api_key}
此外,API 也接受通过 Authorization: Bearer {jwt} 传递的 Firebase JWT,但这仅供 Web 客户端使用,不建议第三方使用。
已通过身份验证的请求示例
curl "https://api.manifold.markets/v0/me" \
-H "Authorization: Key YOUR_API_KEY"
速率限制
每个 IP 地址每分钟最多可发送 500 个请求。请勿使用多个 IP 地址规避此限制。
收到 HTTP 429 响应时,请实施指数退避。
费用
- 通过 API 发布评论会产生 M$1 的交易费用。
- 创建市场需要消耗 mana(各类型的当前费用请参阅市场创建端点)。
许可
- **允许:**机器人、自动交易、算法工具、集成。
- **禁止:**通过 API 以外的方式抓取数据;规避速率限制。
- **AI 训练数据:**未经数据许可,不允许用于商业用途。允许学术用途和个人/非商业用途。商业许可请联系
[email protected]。
REST API 端点概览
所有端点均相对于 https://api.manifold.markets/v0。
用户
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/user/[username] | GET | 否 | 根据用户名获取用户。返回 User。 |
/user/[username]/lite | GET | 否 | 根据用户名获取基本显示信息。返回 DisplayUser。 |
/user/by-id/[id] | GET | 否 | 根据唯一 ID 获取用户。返回 User。 |
/user/by-id/[id]/lite | GET | 否 | 根据 ID 获取显示信息。返回 DisplayUser。 |
/me | GET | 是 | 获取经过身份验证的用户。返回 User。 |
/users | GET | 否 | 按创建日期降序列出所有用户。参数:limit(最大值 1000,默认值 500)、before(用于分页的用户 ID)。 |
User 类型
User {
id: string
createdTime: number
name: string // display name
username: string // used in URLs
url: string
avatarUrl?: string
bio?: string
bannerUrl?: string
website?: string
twitterHandle?: string
discordHandle?: string
isBot?: boolean
isAdmin?: boolean
isTrustworthy?: boolean // moderator
isBannedFromPosting?: boolean
userDeleted?: boolean
balance: number
totalDeposits: number
lastBetTime?: number
currentBettingStreak?: number
}
DisplayUser 类型
DisplayUser {
id: string
name: string
username: string
avatarUrl?: string
}
投资组合
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/get-user-portfolio | GET | 否 | 获取用户实时投资组合指标。参数:userId。 |
/get-user-portfolio-history | GET | 否 | 获取一段时间内的投资组合历史。参数:userId、period(daily、weekly、monthly、allTime)。 |
/get-user-contract-metrics-with-contracts | GET | 否* | 获取用户的持仓及其合约。参数:userId(必需)、limit(必需)、offset、order(lastBetTime 或 profit)、perAnswer。*经过身份验证后,可能会包含你可查看的私人市场指标。 |
PortfolioMetrics 类型
PortfolioMetrics {
investmentValue: number
cashInvestmentValue: number
balance: number
cashBalance: number
spiceBalance: number
totalDeposits: number
totalCashDeposits: number
loanTotal: number
timestamp: number
profit?: number
userId: string
}
LivePortfolioMetrics = PortfolioMetrics & {
dailyProfit: number
}
市场 — 发现与列表
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/markets | GET | 否 | 按创建日期降序列出市场。参数:limit(最大值 1000,默认值 500)、sort(created-time、updated-time、last-bet-time、last-comment-time)、order(asc/desc)、before(用于游标分页的市场 ID)、userId、groupId。返回 LiteMarket[]。 |
/market/[marketId] | GET | 否 | 根据 ID 获取单个市场。返回 FullMarket(包含答案,但不包含投注/评论)。 |
/slug/[marketSlug] | GET | 否 | 根据 slug 获取市场(URL 中用户名之后的路径)。返回 FullMarket。 |
/search-markets | GET | 否 | 搜索/筛选市场(类似浏览页面)。返回 LiteMarket[]。参数见下文。 |
搜索市场参数
| 参数 | 描述 |
|---|---|
term | 搜索查询字符串。可以为空。 |
sort | most-popular(默认)、newest、score、daily-score、freshness-score、24-hour-vol、liquidity、subsidy、last-updated、close-date、start-time、resolve-date、random、bounty-amount、prob-descending、prob-ascending。 |
filter | all(默认)、open、closed、resolved、news、closing-90-days、closing-week、closing-month、closing-day。 |
contractType | ALL(默认)、BINARY、MULTIPLE_CHOICE、DEPENDENT_MULTIPLE_CHOICE、INDEPENDENT_MULTIPLE_CHOICE、BOUNTY、POLL。 |
topicSlug | 仅显示带有此主题 slug 的市场。 |
creatorId | 仅显示此创建者创建的市场。 |
limit | 0–1000(默认 100)。 |
offset | 要跳过的数量(当 sort=newest 时,最大值为 1000)。 |
beforeTime | 用于通过 sort=newest 高效分页的毫秒时间戳游标。传入最后一个结果的 createdTime。 |
liquidity | 每份合约/答案的最低流动性。 |
市场 — 概率
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/market/[marketId]/prob | GET | 否 | 获取当前概率(缓存最长 1s)。二元市场返回 { prob },多选市场返回 { answerProbs: { answerId: prob } }。 |
/market-probs | GET | 否 | 批量获取多个市场的概率(缓存最长 1s)。参数:ids(数组,最多 100 个)。返回 `{ marketId: { prob } |
市场 — 仓位
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/market/[marketId]/positions | GET | 否 | 获取某个市场的仓位数据。参数:order(shares/profit,默认 profit)、top、bottom、userId、answerId。返回 ContractMetric[]。 |
ContractMetric 类型
ContractMetric {
contractId: string
from: {
[period: string]: { // day, week, month
profit: number
profitPercent: number
invested: number
prevValue: number
value: number
}
} | undefined
hasNoShares: boolean
hasShares: boolean
hasYesShares: boolean
invested: number
loan: number
maxSharesOutcome: string | null
payout: number
profit: number
profitPercent: number
totalShares: { [outcome: string]: number }
userId: string
userUsername: string
userName: string
userAvatarUrl: string
lastBetTime: number
}
市场 — 创建与管理
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/market | POST | 是 | 创建新市场。返回 LiteMarket。参数见下文。 |
/market/[marketId]/answer | POST | 是 | 为 MULTIPLE_CHOICE 市场添加答案。参数:text。 |
/market/[marketId]/add-liquidity | POST | 是 | 向流动性池添加 mana(不会提升流动性)。参数:amount。 |
/market/[marketId]/add-bounty | POST | 是 | 为悬赏问题的奖励添加 mana。参数:amount。 |
/market/[marketId]/award-bounty | POST | 是 | 发放悬赏奖励。参数:amount、commentId。 |
/market/[marketId]/close | POST | 是 | 设置关闭时间。参数:closeTime(自纪元起的毫秒数;省略则立即关闭)。 |
/market/[marketId]/group | POST | 是 | 添加/移除主题标签。参数:groupId、remove(可选,true 表示移除标签)。 |
/market/[marketId]/resolve | POST | 是 | 判定市场结果。判定格式见下文。 |
市场创建参数
通用参数(所有市场类型):
| 参数 | 必填 | 描述 |
|---|---|---|
outcomeType | 是 | BINARY、MULTIPLE_CHOICE、PSEUDO_NUMERIC、POLL、BOUNTIED_QUESTION。 |
question | 是 | 标题问题。 |
description | 否 | 纯文本描述。也可以使用 descriptionHtml、descriptionMarkdown 或 descriptionJson(序列化后的 TipTap JSON)。 |
closeTime | 否 | 市场关闭时间(自纪元起的毫秒数)。默认为从现在起 7 天后。 |
visibility | 否 | public(默认)或 unlisted。 |
groupIds | 否 | 要添加标签的主题 ID 数组。 |
extraLiquidity | 否 | 要增加的额外流动性。 |
各类型的额外参数:
| 类型 | 额外参数 |
|---|---|
| BINARY | initialProb(1–99,必填) |
| PSEUDO_NUMERIC | min、max、isLogScale、initialValue(均为必填) |
| MULTIPLE_CHOICE | answers(string[],必填)、addAnswersMode(DISABLED/ONLY_CREATOR/ANYONE,默认为 DISABLED)、shouldAnswersSumToOne(boolean) |
| BOUNTIED_QUESTION | totalBounty(必填) |
| POLL | answers(string[],必填) |
创建费用:
| 类型 | 费用 |
|---|---|
| BINARY | M$50 |
| PSEUDO_NUMERIC | M$250 |
| MULTIPLE_CHOICE | 每个答案 M$25,或不预设答案时 M$25 |
结算格式
二元市场:
outcome:YES、NO、MKT或CANCEL。probabilityInt:可选,在结算为MKT时使用。
多选市场(shouldAnswersSumToOne = true):
{
"outcome": "MKT",
"resolutions": [
{ "answer": <index>, "pct": <weight> }
]
}
权重之和必须为 100。也可以将 outcome 设为表示单个答案索引的数字,或设为 CANCEL。
多选市场(shouldAnswersSumToOne = false): 分别发送单独请求,对每个答案进行结算:
{
"outcome": "YES", // or "NO"
"answerId": "<answer_id>"
}
数值市场:
outcome:CANCEL或数值档位 ID。value:结算值。- 提供
value时必须提供probabilityInt。
交易
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/bet | POST | 是 | 下投注或限价单。返回 Bet。 |
/multi-bet | POST | 是 | 在答案权重之和为 1 的多选市场中,为多个答案下 YES 投注,使每个答案的份额相等。返回 Bet[]。 |
/bet/cancel/[id] | POST | 是 | 取消未成交的限价单。 |
/market/[marketId]/sell | POST | 是 | 卖出份额。参数:outcome(YES/NO,默认为持有的类型)、shares(可选,默认为全部)、answerId(多选市场必填)。 |
投注参数
| 参数 | 必填 | 描述 |
|---|---|---|
amount | 是 | 投注的 mana 数量,不含手续费。 |
contractId | 是 | 市场 ID。 |
outcome | 否 | YES(默认)或 NO。 |
limitProb | 否 | 将其设为限价单。数值范围为 0.01 至 0.99(仅支持整百分比点,例如 0.01 = 1%)。 |
expiresAt | 否 | 限价单自动取消的时间戳(毫秒)。 |
expiresMillisAfter | 否 | 创建后经过指定毫秒数后自动取消。 |
dryRun | 否 | 若为 true,则模拟操作而不实际下单。 |
多笔投注参数
| 参数 | 必填 | 描述 |
|---|---|---|
contractId | 是 | 市场 ID。必须是 cpmm-multi-1,且 shouldAnswersSumToOne=true。 |
answerIds | 是 | 答案 ID 数组(至少 2 个)。 |
amount | 是 | 在所选答案上花费的 mana 总量。 |
limitProb | 否 | 每笔交易的限价(0.01–0.99,精确到小数点后两位)。 |
expiresAt | 否 | 未成交部分自动取消的时间戳(毫秒)。 |
评论
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/comment | POST | 是 | 在市场中创建顶层评论。参数:contractId,以及 content(TipTap JSON)、html 或 markdown 之一。费用:M$1。 |
/comments | GET | 否 | 列出市场或用户的评论。参数:contractId、contractSlug、limit(最大 1000)、page、userId、order(likes/newest/oldest)。 |
Bets
| Endpoint | Method | Auth | 说明 |
|---|---|---|---|
/bets | GET | No | 列出投注。参数:userId、username、contractId(可以有多个)、contractSlug、limit(最大值为 1000)、before/after(投注 ID 游标)、beforeTime/afterTime(时间戳)、kinds(open-limit)、order(asc/desc)。 |
Bet Type
Bet {
id: string
contractId: string
userId: string
amount: number // mana spent (filled portion for limits)
orderAmount: number // original order amount
shares: number
outcome: "YES" | "NO"
probBefore: number
probAfter: number
createdTime: number
fees: {
creatorFee: number
platformFee: number
liquidityFee: number
}
isFilled: boolean
isCancelled: boolean
loanAmount: number
limitProb?: number // present for limit orders
fills: Fill[]
answerId?: string // for multi-choice markets
}
Fill {
matchedBetId: string | null
amount: number
shares: number
timestamp: number
fees: { creatorFee: number; platformFee: number; liquidityFee: number }
}
Topics(群组)
| Endpoint | Method | Auth | 说明 |
|---|---|---|---|
/groups | GET | No | 列出公开主题,每次 500 个,按时间从新到旧排序。参数:beforeTime、availableToUserId。 |
/group/[slug] | GET | No | 按 slug 获取主题。 |
/group/by-id/[id] | GET | No | 按 ID 获取主题。 |
Mana 转账
| Endpoint | Method | Auth | 说明 |
|---|---|---|---|
/managram | POST | Yes | 向其他用户发送 mana。参数:toIds(用户 ID 数组)、amount(>= 10,向每位用户发送的数量)、message(可选)。 |
Transactions
| Endpoint | Method | Auth | 说明 |
|---|---|---|---|
/txns | GET | No | 列出交易,按时间从新到旧排序。参数:token(CASH/MANA)、offset、limit(最大值为 100)、before/after(时间戳)、toId、fromId、category。 |
Leagues
| Endpoint | Method | Auth | 说明 |
|---|---|---|---|
/leagues | GET | No | 获取联赛排名。参数:userId、season(数字)、cohort(字符串)。 |
市场类型
outcomeType | mechanism | 说明 |
|---|---|---|
BINARY | cpmm-1 | 是/否市场,具有单一概率(0–1)。最常见的类型。 |
MULTIPLE_CHOICE | cpmm-multi-1 | 多个选项,每个选项都有自己的概率。可以是相关选项(总和为 100%),也可以相互独立。 |
FREE_RESPONSE | dpm-2 | 旧版类型。任何人都可以添加答案。使用 DPM 机制。 |
PSEUDO_NUMERIC | cpmm-1 | 将概率映射到数值范围 [min, max]。可以使用线性或对数刻度。 |
BOUNTIED_QUESTION | — | 不支持交易。创建者将赏金分配给最佳评论。 |
POLL | — | 不支持交易。用户为选项投票。 |
LiteMarket Type
LiteMarket {
id: string
creatorId: string
creatorUsername: string
creatorName: string
creatorAvatarUrl?: string
createdTime: number
closeTime?: number
question: string
url: string // always points to manifold.markets
outcomeType: string
mechanism: string
probability: number
pool: { [outcome: string]: number }
p?: number // CPMM probability constant
totalLiquidity?: number // CPMM only
value?: number // PSEUDO_NUMERIC only
min?: number // PSEUDO_NUMERIC only
max?: number // PSEUDO_NUMERIC only
isLogScale?: boolean // PSEUDO_NUMERIC only
volume: number
volume24Hours: number
isResolved: boolean
resolutionTime?: number
resolution?: string
resolutionProbability?: number // for MKT resolution
uniqueBettorCount: number
lastUpdatedTime?: number
lastBetTime?: number
token?: "MANA" | "CASH"
siblingContractId?: string // toggle between mana/cash version
}
FullMarket Type
FullMarket = LiteMarket & {
answers?: Answer[] // multi markets only
shouldAnswersSumToOne?: boolean // multi markets only
addAnswersMode?: "ANYONE" | "ONLY_CREATOR" | "DISABLED"
options?: { text: string; votes: number }[] // poll only
totalBounty?: number // bounty only
bountyLeft?: number // bounty only
description: JSONContent // TipTap rich text
textDescription: string // plain text
coverImageUrl?: string
groupSlugs?: string[] // topic tags
}
WebSocket API
Manifold 提供实时 WebSocket 服务,用于订阅实时更新。
连接
wss://api.manifold.markets/ws (production)
wss://api.dev.manifold.markets/ws (dev)
连接无需身份验证。身份验证为可选项(适用于特定用户主题)。
消息格式
所有消息均为 JSON。客户端消息必须包含:
type:identify、subscribe、unsubscribe或ping。txid:用于标识消息的唯一编号。
服务器会确认每条消息:
{ "type": "ack", "txid": 123, "success": true }
订阅主题
发送订阅消息:
{
"type": "subscribe",
"txid": 1,
"topics": ["global/new-bet", "contract/[marketId]"]
}
可用主题
全局主题
| Topic | 说明 |
|---|---|
global/new-bet | 所有市场中的所有新投注。 |
global/new-contract | 所有新建的市场。 |
global/new-comment | 所有市场中的所有新评论。 |
global/new-subsidy | 所有新的流动性补贴。 |
global/updated-contract | 任何公开市场的更新。 |
单个市场主题(将 [marketId] 替换为实际 ID)
| Topic | 说明 |
|---|---|
contract/[marketId] | 市场常规更新。 |
contract/[marketId]/new-bet | 此市场的新投注。 |
contract/[marketId]/new-comment | 此市场的新评论。 |
contract/[marketId]/new-subsidy | 新的流动性补贴。 |
contract/[marketId]/new-answer | 新添加的答案(多选)。 |
contract/[marketId]/updated-answers | 现有答案的更新。 |
contract/[marketId]/orders | 限价单更新。 |
contract/[marketId]/chart-annotation | 图表注释。 |
contract/[marketId]/user-metrics/[userId] | 此市场中的用户持仓更新。 |
其他主题
| Topic | 说明 |
|---|---|
user/[userId] | 用户公开信息的更新。 |
answer/[answerId]/update | 特定答案的更新。 |
tv_schedule | 电视节目表更新。 |
保持连接
每隔 30–60 秒发送一次定期 ping,以保持连接。若 60 秒内未收到 ping,服务端将终止连接。
{ "type": "ping", "txid": 42 }
广播消息
服务端会以广播消息的形式发送更新:
{
"type": "broadcast",
"topic": "global/new-bet",
"data": { ... }
}
常见模式
列出最近的市场
curl -s "https://api.manifold.markets/v0/markets?limit=5" | jq '.[].question'
按 ID 获取单个市场
curl -s "https://api.manifold.markets/v0/market/3zspH9sSzMlbFQLn9GKR" | jq '{question, probability, volume, isResolved}'
按 slug 获取市场
curl -s "https://api.manifold.markets/v0/slug/will-carrick-flynn-win-the-general" | jq '{question, probability}'
搜索开放的二元市场
curl -s "https://api.manifold.markets/v0/search-markets?term=AI&sort=liquidity&filter=open&contractType=BINARY&limit=10" | jq '.[].question'
获取当前概率
curl -s "https://api.manifold.markets/v0/market/9t61v9e7x4/prob" | jq '.'
批量获取概率
curl -s "https://api.manifold.markets/v0/market-probs?ids=9t61v9e7x4&ids=ZNlNdzz690" | jq '.'
下 YES 注
curl -X POST "https://api.manifold.markets/v0/bet" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amount": 10, "contractId": "MARKET_ID", "outcome": "YES"}'
下限价单
curl -X POST "https://api.manifold.markets/v0/bet" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 100,
"contractId": "MARKET_ID",
"outcome": "YES",
"limitProb": 0.40,
"expiresMillisAfter": 86400000
}'
卖出某个市场中的所有份额
curl -X POST "https://api.manifold.markets/v0/market/MARKET_ID/sell" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"outcome": "YES"}'
取消限价单
curl -X POST "https://api.manifold.markets/v0/bet/cancel/BET_ID" \
-H "Authorization: Key YOUR_API_KEY"
创建二元市场
curl -X POST "https://api.manifold.markets/v0/market" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"outcomeType": "BINARY",
"question": "Will it rain in SF tomorrow?",
"descriptionMarkdown": "Resolves YES if measurable rainfall is recorded at SFO weather station.",
"initialProb": 30,
"closeTime": 1735689600000
}'
创建多选市场
curl -X POST "https://api.manifold.markets/v0/market" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"outcomeType": "MULTIPLE_CHOICE",
"question": "Who will win the award?",
"answers": ["Alice", "Bob", "Charlie"],
"shouldAnswersSumToOne": true,
"addAnswersMode": "ONLY_CREATOR"
}'
结算二元市场
curl -X POST "https://api.manifold.markets/v0/market/MARKET_ID/resolve" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"outcome": "YES"}'
获取你的投资组合
curl -s "https://api.manifold.markets/v0/get-user-portfolio?userId=YOUR_USER_ID" | jq '.'
获取某个市场中的热门持仓
curl -s "https://api.manifold.markets/v0/market/MARKET_ID/positions?top=5&order=profit" | jq '.[].userName'
翻页获取所有市场(按最新排序)
# Page 1
curl -s "https://api.manifold.markets/v0/search-markets?sort=newest&limit=100" > page1.json
# Page 2: use createdTime of last result
BEFORE_TIME=$(jq '.[-1].createdTime' page1.json)
curl -s "https://api.manifold.markets/v0/search-markets?sort=newest&limit=100&beforeTime=$BEFORE_TIME" > page2.json
翻页获取投注记录
# First page
curl -s "https://api.manifold.markets/v0/bets?contractId=MARKET_ID&limit=100" > bets1.json
# Next page: use ID of last bet
BEFORE=$(jq -r '.[-1].id' bets1.json)
curl -s "https://api.manifold.markets/v0/bets?contractId=MARKET_ID&limit=100&before=$BEFORE" > bets2.json
向用户发送 Mana
curl -X POST "https://api.manifold.markets/v0/managram" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"toIds": ["USER_ID_1", "USER_ID_2"], "amount": 100, "message": "Thanks!"}'
发布评论
curl -X POST "https://api.manifold.markets/v0/comment" \
-H "Authorization: Key YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"contractId": "MARKET_ID", "markdown": "Great question! I think YES is undervalued."}'
WebSocket 订阅(Node.js)
const ws = new WebSocket("wss://api.manifold.markets/ws");
let txid = 0;
ws.onopen = () => {
ws.send(JSON.stringify({
type: "subscribe",
txid: txid++,
topics: ["global/new-bet"]
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "broadcast") {
console.log("New bet:", msg.data);
}
};
// Keep-alive ping every 30 seconds
setInterval(() => {
ws.send(JSON.stringify({ type: "ping", txid: txid++ }));
}, 30000);
使用提示
- 所有时间戳均为 UNIX 毫秒(JavaScript
Date.now()格式),而非秒。 - 切勿将 API 密钥硬编码——请使用环境变量或安全的密钥存储。
- 市场 URL 始终指向
https://manifold.markets,无论你使用哪个 API 实例。URL 路径中的用户名不必正确(例如,manifold.markets/anyone/market-slug也能正常使用)。 - GET 参数放在查询字符串中。POST/PUT 参数放在 JSON 请求体中。
- 使用
limitProb下的限价单若跨越当前市场价格,将立即部分成交。任何未成交的剩余部分都会作为挂单保留。 limitProb精度:仅支持整数百分点(两位小数,例如0.01、0.50、0.99)。- 多选市场分为两种:相依型(
shouldAnswersSumToOne=true,概率总和为 100%)和独立型(每个答案实际上都是一个单独的二元市场)。 - 结合使用 REST + WebSocket 可获得最佳效果:使用 REST 获取初始状态,使用 WebSocket 获取实时增量更新。
- 合理翻页:对于
sort=newest的/search-markets,使用beforeTime高效地进行深度翻页。对于/bets和/markets,使用基于游标的翻页,并搭配before/after。 - 市场代币类型很重要:检查
token字段(MANA或CASH),以了解市场使用的是游戏币还是奖金现金。 - 传入
dryRun: true可模拟投注,而不实际下单。 - 描述格式:你可以使用纯文本(
description)、HTML(descriptionHtml)、Markdown(descriptionMarkdown)或 TipTap JSON(descriptionJson)提供市场描述。只能提供其中一种。
错误处理
API 响应均为 JSON。成功请求会返回 HTTP 200 和 JSON 结果。错误响应(4xx/5xx)会返回带有错误消息的 JSON 对象。
| 状态 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 错误请求(参数无效) |
| 401 | 未授权(缺少或无效的 API 密钥) |
| 403 | 禁止访问(权限不足) |
| 404 | 未找到 |
| 429 | 请求受限(超过 500 req/min) |
| 5xx | 服务端错误 |
对于 429 和 5xx 响应,请使用指数退避进行重试。
内部 API
Manifold 有一些不属于官方 API 的内部端点。这些端点没有文档说明,且可能随时变更,恕不另行通知。
| 端点 | 方法 | 身份验证 | 描述 |
|---|---|---|---|
/unresolve | POST | 是 | 取消市场结算。参数:contractId。 |
注意:内部端点没有以 /v0 为前缀。
版本控制
当前 API 版本为 /v0/ 下的 v0。该 API 仍处于 alpha 阶段。请关注官方文档和 Discord,以了解可能导致不兼容的变更。