manifold について
manifold は、Manifold の予測市場 API を扱うためのスキルです。開発者が市場の検索やデータ取得、取引、マーケット管理をプログラムから行う際に役立ちます。
主な機能
- 01市場の検索と一覧表示
- 02確率とポジションの取得
- 03ユーザーとポートフォリオ情報の取得
- 04市場の作成と管理
- 05取引と流動性の管理
活用シーン
- 01市場検索ツールの構築
- 02市場確率とポジションの分析
- 03APIを使った取引の自動化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ outsharp/ shipp-skills --skill manifoldインストール後、Claude Code で/manifoldを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
Manifold API
Manifold は、ユーザーが現実の出来事に関する質問を作成し、取引できる予測市場プラットフォームです。プレイマネー(mana)と賞金現金を組み合わせて使用し、自動マーケットメーカー(CPMM)と、プログラムからアクセスできる豊富な API を備えています。
このスキルと公式ドキュメントを頻繁に確認して、最新情報をチェックしてください。API はまだアルファ版であり、予告なく変更される場合があります。
コミュニティ: 質問やバグ報告、作成したものの共有には、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 | 動的パリミュチュエル市場です。旧式の自由回答市場で使われていたレガシー方式(dpm-2)です。 |
| 確率 | YES の現在の市場推定確率を表す、0 から 1 までの数値です。 |
| プール | マーケットメーカーを支える株式の流動性プールです。CPMM 市場では、YES と NO の株式数が表示されます。 |
| 流動性 | AMM プールに預け入れられた mana です。流動性が高いほど、取引ごとの価格への影響が小さくなります。 |
| ベット | 市場での取引です。成行注文または指値注文(limitProb が指定されている場合)を行えます。 |
| 指値注文 | 指定した確率価格以上の条件でのみ執行されるベットです。約定、キャンセル、または期限切れになるまで有効です。 |
| 株式 | ポジションの単位です。勝った YES 株式は 1 株あたり M$1 を受け取り、負けた株式は M$0 を受け取ります。 |
| 決着 | 市場の最終結果です。YES、NO、MKT(確率)、または CANCEL です。 |
| 回答 | MULTIPLE_CHOICE または FREE_RESPONSE 市場で考えられる結果です。各回答にはそれぞれ確率があります。 |
| 賞金 | 作成者が優れたコメントや回答に mana の報酬を配布する BOUNTIED_QUESTION 市場です。 |
| 投票 | ユーザーが選択肢に投票するだけの、取引を伴わない市場タイプです。 |
ベース 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/ がプレフィックスとして付きます。
ドキュメントと参考資料
| リソース | URL |
|---|---|
| API ドキュメント | https://docs.manifold.markets/api |
| プラットフォーム | https://manifold.markets |
| ソースコード(GitHub) | https://github.com/manifoldmarkets/manifold |
| API 型定義 | https://github.com/manifoldmarkets/manifold/tree/main/common/src/api/schema.ts |
| Discord コミュニティ | https://discord.com/invite/eHQBNBqXuh |
| 利用規約 | https://docs.manifold.markets/terms |
| データのダウンロードとライセンス | https://docs.manifold.markets/data |
認証
一部のエンドポイントは公開されており、認証は不要です。書き込みエンドポイントとユーザー固有の読み取りには、API キーによる認証が必要です。
API キーの生成
- Manifold にログインします。
- ユーザープロフィールに移動し、「edit」をクリックします。
- 下までスクロールして、最下部にある API キーのフィールドを表示します。
- 「refresh」ボタンをクリックして、新しいキーを生成します。
- キーをコピーし、安全に保管します。「refresh」を再度クリックすると、古いキーは無効になり、新しいキーが生成されます。
API キーの使用
Authorization ヘッダーにキーを含めます。
Authorization: Key {your_api_key}
また、API は Authorization: Bearer {jwt} による Firebase JWT も受け付けますが、これはウェブクライアント向けであり、サードパーティでの使用は推奨されません。
認証済みリクエストの例
curl "https://api.manifold.markets/v0/me" \
-H "Authorization: Key YOUR_API_KEY"
レート制限
IP アドレスごとに毎分 500 リクエストのレート制限があります。この制限を回避するために、複数の IP アドレスを使用しないでください。
HTTP 429 レスポンスに対して、指数バックオフを実装してください。
手数料
- API 経由で投稿されたコメントには、M$1 の取引手数料がかかります。
- 市場の作成にはマナが必要です(種類ごとの現在のコストについては、市場作成エンドポイントを参照してください)。
ライセンス
- 許可される用途: ボット、自動取引、アルゴリズムツール、統合。
- 禁止事項: API 以外の手段によるスクレイピング、レート制限の回避。
- AI のトレーニングデータ: データライセンスなしでの商用利用は許可されていません。学術利用および個人利用・非商用利用は許可されています。商用ライセンスについては
[email protected]までお問い合わせください。
REST API エンドポイントの概要
すべてのエンドポイントは https://api.manifold.markets/v0 を基準とします。
ユーザー
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/user/[username] | GET | No | ユーザー名でユーザーを取得します。User を返します。 |
/user/[username]/lite | GET | No | ユーザー名で基本的な表示情報を取得します。DisplayUser を返します。 |
/user/by-id/[id] | GET | No | 一意の ID でユーザーを取得します。User を返します。 |
/user/by-id/[id]/lite | GET | No | ID で表示情報を取得します。DisplayUser を返します。 |
/me | GET | Yes | 認証済みユーザーを取得します。User を返します。 |
/users | GET | No | 作成日の降順ですべてのユーザーを一覧表示します。パラメーター: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
}
ポートフォリオ
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/get-user-portfolio | GET | No | ユーザーの現在のポートフォリオ指標を取得します。パラメーター:userId。 |
/get-user-portfolio-history | GET | No | 期間を指定してポートフォリオ履歴を取得します。パラメーター:userId、period(daily、weekly、monthly、allTime)。 |
/get-user-contract-metrics-with-contracts | GET | No* | ユーザーのポジションとその契約を取得します。パラメーター: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
}
市場 — 検索と一覧表示
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/markets | GET | No | 作成日の降順で市場を一覧表示します。パラメーター: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 | No | ID で単一の市場を取得します。FullMarket を返します(回答を含みますが、賭けやコメントは含みません)。 |
/slug/[marketSlug] | GET | No | スラッグで市場を取得します(ユーザー名の後に続く URL パス)。FullMarket を返します。 |
/search-markets | GET | No | 市場を検索・フィルタリングします(閲覧ページと同様)。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 | このトピックスラッグが付いたマーケットのみ。 |
creatorId | この作成者によるマーケットのみ。 |
limit | 0~1000(デフォルトは100)。 |
offset | スキップする件数(sort=newest の場合、最大1000)。 |
beforeTime | sort=newest での効率的なページネーションに使用する、ミリ秒単位のタイムスタンプカーソル。最後の結果の createdTime を渡します。 |
liquidity | コントラクト/回答ごとの最小流動性。 |
マーケット — 確率
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/market/[marketId]/prob | GET | 不要 | 現在の確率を取得します(最大1秒のキャッシュ)。バイナリーの場合は { prob }、複数選択の場合は { answerProbs: { answerId: prob } } を返します。 |
/market-probs | GET | 不要 | 複数のマーケットの確率を一括取得します(最大1秒のキャッシュ)。パラメーター: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 | 必要 | 流動性プールにマナを追加します(ブーストはされません)。パラメーター:amount。 |
/market/[marketId]/add-bounty | POST | 必要 | バウンティ形式の質問の報酬にマナを追加します。パラメーター: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(ブール値) |
| BOUNTIED_QUESTION | totalBounty(必須) |
| POLL | answers(string[]、必須) |
作成コスト:
| タイプ | コスト |
|---|---|
| BINARY | M$50 |
| PSEUDO_NUMERIC | M$250 |
| MULTIPLE_CHOICE | 回答1つにつき M$25、または事前設定の回答なしの場合は M$25 |
決着形式
Binary 市場:
outcome:YES、NO、MKT、またはCANCEL。probabilityInt:省略可能です。MKTで決着させる場合に使用します。
Multiple Choice(shouldAnswersSumToOne = true):
{
"outcome": "MKT",
"resolutions": [
{ "answer": <index>, "pct": <weight> }
]
}
重みの合計は100にする必要があります。または、単一の回答インデックスを数値で指定する outcome、あるいは CANCEL を使用します。
Multiple Choice(shouldAnswersSumToOne = false): 回答ごとに別々のリクエストを送信して、個別に決着させます:
{
"outcome": "YES", // or "NO"
"answerId": "<answer_id>"
}
数値市場:
outcome:CANCELまたは数値バケット ID。value:決着値。probabilityInt:valueを指定する場合は必須です。
取引
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/bet | POST | はい | ベットまたは指値注文を出します。Bet を返します。 |
/multi-bet | POST | はい | 合計が1になる複数選択市場で複数の YES ベットを出し、各回答のシェアが均等になるようにします。Bet[] を返します。 |
/bet/cancel/[id] | POST | はい | 未約定の指値注文をキャンセルします。 |
/market/[marketId]/sell | POST | はい | シェアを売却します。パラメーター:outcome(YES/NO、デフォルトは保有する側)、shares(省略可能、デフォルトは全数)、answerId(複数選択の場合は必須)。 |
ベットパラメーター
| パラメーター | 必須 | 説明 |
|---|---|---|
amount | はい | 手数料を差し引く前にベットするマナの額。 |
contractId | はい | 市場 ID。 |
outcome | いいえ | YES(デフォルト)または NO。 |
limitProb | いいえ | 指値注文にします。0.01~0.99の数値(整数パーセントポイントのみ。例:0.01 = 1%)。 |
expiresAt | いいえ | 指値注文が自動キャンセルされる時刻のタイムスタンプ(ミリ秒)。 |
expiresMillisAfter | いいえ | 作成から自動キャンセルまでのミリ秒数。 |
dryRun | いいえ | true の場合、注文を出さずにシミュレーションします。 |
複数ベットのパラメーター
| パラメーター | 必須 | 説明 |
|---|---|---|
contractId | はい | 市場 ID。shouldAnswersSumToOne=true の cpmm-multi-1 である必要があります。 |
answerIds | はい | 回答 ID の配列(最小2件)。 |
amount | はい | 選択した回答全体に使用するマナの合計額。 |
limitProb | いいえ | 各レッグの指値価格(0.01~0.99、小数点以下2桁)。 |
expiresAt | いいえ | 未約定分が自動キャンセルされる時刻のタイムスタンプ(ミリ秒)。 |
コメント
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/comment | POST | はい | 市場にトップレベルのコメントを作成します。パラメーター:contractId と、content(TipTap JSON)、html、markdown のいずれか。手数料:M$1。 |
/comments | GET | いいえ | 市場またはユーザーのコメントを一覧表示します。パラメーター:contractId、contractSlug、limit(最大1000)、page、userId、order(likes/newest/oldest)。 |
賭け
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/bets | GET | なし | 賭けの一覧を取得します。パラメーター:userId、username、contractId(複数指定可能)、contractSlug、limit(最大 1000)、before/after(賭け ID のカーソル)、beforeTime/afterTime(タイムスタンプ)、kinds(open-limit)、order(asc/desc)。 |
賭けの型
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 }
}
トピック(グループ)
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/groups | GET | なし | 公開トピックを新しい順に 500 件ずつ取得します。パラメーター:beforeTime、availableToUserId。 |
/group/[slug] | GET | なし | スラッグでトピックを取得します。 |
/group/by-id/[id] | GET | なし | ID でトピックを取得します。 |
マナの送金
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/managram | POST | あり | 他のユーザーにマナを送ります。パラメーター:toIds(ユーザー ID の配列)、amount(10 以上。各ユーザーに送られます)、message(任意)。 |
トランザクション
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/txns | GET | なし | トランザクションを新しい順に取得します。パラメーター:token(CASH/MANA)、offset、limit(最大 100)、before/after(タイムスタンプ)、toId、fromId、category。 |
リーグ
| エンドポイント | メソッド | 認証 | 説明 |
|---|---|---|---|
/leagues | GET | なし | リーグの順位を取得します。パラメーター: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 の型
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 の型
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 }
トピックの購読
subscribe メッセージを送信します。
{
"type": "subscribe",
"txid": 1,
"topics": ["global/new-bet", "contract/[marketId]"]
}
利用可能なトピック
グローバルトピック
| トピック | 説明 |
|---|---|
global/new-bet | すべての市場での新しい賭け。 |
global/new-contract | 新しく作成されたすべての市場。 |
global/new-comment | すべての市場での新しいコメント。 |
global/new-subsidy | 新しい流動性補助金。 |
global/updated-contract | 公開市場の更新。 |
市場ごとのトピック([marketId] を実際の ID に置き換えてください)
| トピック | 説明 |
|---|---|
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] | この市場におけるユーザーのポジション更新。 |
その他のトピック
| トピック | 説明 |
|---|---|
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}'
スラッグでマーケットを取得
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は、使用しているAPIインスタンスにかかわらず、常に
https://manifold.marketsを指します。URLパス内のユーザー名は正確である必要はありません(例:manifold.markets/anyone/market-slugでも機能します)。 - GETパラメーターはクエリ文字列に指定します。POST/PUTパラメーターはJSONボディに指定します。
- 現在のマーケット価格をまたぐ
limitProbを指定した指値注文は、一部が即座に約定します。約定しなかった残りの注文は、未約定の指値注文として残ります。 limitProbの精度:指定できるのは整数パーセント単位(小数点以下2桁、例:0.01、0.50、0.99)のみです。- 複数選択マーケットには、依存型(
shouldAnswersSumToOne=trueで、確率の合計が100%)と独立型(各回答が実質的に個別の二択マーケット)の2種類があります。 - 最良の結果を得るには、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)を指定できます。指定するのは1つだけにしてください。
エラー処理
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はまだアルファ版です。破壊的変更については、公式ドキュメントとDiscordを確認してください。