Skip to content

クイックスタート

Freeキーで最初のマッチング済みフィードをREST経由で取得し、続いてリアルタイムストリームに接続します。

このガイドでは、ゼロから約2分でライブデータを取得するところまでを説明します。前半はFreeキーで実行できます。後半ではリアルタイムストリームに接続するため、BasicまたはProプランが必要です。

まず、APIキーを作成します。ダッシュボードを開き、GitHubまたはGoogleでサインインしてキーを作成してください。キーは一度しか表示されないので、どこか安全な場所にコピーしておきましょう。新しいキーはすべてFreeから始まり、前半にはそれで十分です。

RESTによるマッチング済みフィード

RESTスナップショットは、リクエストすればアービトラージビューで価格付けされた、マッチング済みフィードを返します。レスポンスを小さく保つため、1つのスポーツを指定しましょう。キーはbearerトークンとして送信します。

curl -s "https://api.dino.markets/v2/markets?signal=arb&sport=baseball" \
  -H "Authorization: Bearer sk_live_..."

そのスポーツのスナップショットが返ってきます。以下は確定済みアービトラージの一例です。

{
  "count": 1,
  "sport": "baseball",
  "has_more": false,
  "markets": [
    {
      "id": "dino_8f3a1c92-47e8-4c3f-b9d2-f1a8e6c4d5f2",
      "slug": null,
      "sport": "baseball",
      "league": "MLB",
      "title": "Nyy vs Bos",
      "home": null,
      "away": null,
      "start_time": "2026-07-01T23:05:00+00:00",
      "status": "open",
      "match": "high_confidence",
      "signal": "arb",
      "spread_pts": 2.0,
      "potential_arb_pct": 1.83,
      "coverage": { "kalshi": true, "polymarket": true },
      "outcomes": [
        { "key": "NYY", "name": "NYY", "kalshi": 0.52, "polymarket": 0.54, "cheaper": "kalshi" },
        { "key": "BOS", "name": "BOS", "kalshi": 0.50, "polymarket": 0.46, "cheaper": "polymarket" }
      ],
      "result": null,
      "updated_at": "2026-07-01T22:55:00+00:00",
      "priced_at": "2026-07-01T22:55:00+00:00",
      "links": { "kalshi": "https://kalshi.com/markets/KXMLBGAME-26JUL01NYYBOS", "polymarket": null }
    }
  ]
}

GET /v2/markets?signal=arb は、価格が付いた正規のmarketオブジェクトを返します。potential_arb_pct は、venue手数料を差し引く前の、ask同士のグロスリターンです。outcomes は各市場のoutcomeを、両venueでの価格と、どちらのvenueのaskが安いか(cheaper)とともに列挙します。signal は、マッチングエンジンが決着済みoutcomeについて venue間の解決パリティを確認済みの場合に "arb" になります。それ以外は、解決リスクが開示されているマッチ済みのギャップも含め、すべて "spread" として返ります。いずれの場合も、行動を起こす前に settlement.risks を確認してください。include=settlement を付けるか、下記の詳細エンドポイントを呼び出してください。

完全な詳細(venueのハンドル、確信度、解決の開示)を得るには、行の id を使って GET /v2/pairs/{market_id} を呼び出します。この詳細は、マッチングエンジンがライブのテキストを再分析したときにのみ変わるので、キャッシュして構いません。

何も開いていないとき、markets は空配列になり count0 です。これはアービトラージとアービトラージの間にある通常の待機状態であり、エラーではありません。sportlimit でスナップショットをさらに絞り込めます。

リアルタイムストリーム

RESTスナップショットは約2分遅延しているため、探索向けです。アービトラージが開いた瞬間に行動するには、WebSocketストリームを読んでください。これにはBasicまたはProキーが必要です。

ストリームは2段階のハンドシェイクです。まずRESTで短命のチケットを発行し、それを使ってソケットを開きます。Freeキーはここで、アップグレードへのリンク付きの 402 を受け取ります。

ステップ1、チケットを発行します。有効期間は約120秒です。

curl -s -X POST "https://api.dino.markets/v1/stream/token" \
  -H "Authorization: Bearer sk_live_..."
{
  "ticket": "eyJhbGciOi...",
  "ws_url": "wss://stream.dino.markets/connection/websocket",
  "expires_in": 120,
  "allowed": {
    "channels": ["markets:all", "status"],
    "max_conns": 3
  }
}

ステップ2、接続します。ストリームはCentrifugoプロトコルを話すので、お使いの言語向けの centrifuge クライアントを使い、接続データの t にチケットを渡します。手動でのチャンネル購読は不要です。サーバーがチケットからあなたのプランを読み取り、権限のあるチャンネルを配信します。

import { Centrifuge } from "centrifuge";

const centrifuge = new Centrifuge("wss://stream.dino.markets/connection/websocket", {
  data: { t: ticket },
});

centrifuge.on("publication", (ctx) => {
  console.log(ctx.channel, ctx.data);
});

centrifuge.connect();

チケットが短命なのは意図的な設計です。新しい接続ごとに新しいチケットを発行してください。一度確立した接続はクライアントが維持するので、再発行が必要になるのはゼロから再接続するときだけです。

メッセージは何かが変化した瞬間にプッシュされます。markets:* チャンネルでは market 状態フレームと price 差分フレームが届き、ペアのsignalが arb のときは、そのフレームに outcome ごとの板の厚み(デプス)情報と max_stake も付与されます。各フレームの形状はWebSocketストリームページで解説しています。

次に読むページ

Marketオブジェクトリファレンスでは、正規のオブジェクト形状、outcomes 配列、signalの種類、ストリームのエンベロープを解説しています。WebSocketストリームページでは、接続方法と切断後の復旧方法を解説しています。venueのハンドルと解決条件については、RESTリファレンスに記載されている GET /v2/pairs/{market_id} を使ってください。