terra-streaming について
terra-streaming は、Terra API でウェアラブルのリアルタイムデータを扱うアプリの構築を支援するスキルです。プロデューサーとコンシューマーの構成、トークン、WebSocket プロトコルや注意点を開発者向けに解説します。
主な機能
- 01プロデューサーとコンシューマーの構成ガイド
- 02トークンのライフサイクルと認証
- 03WebSocket プロトコルとリプレイの詳細
- 04ウェアラブルのデータ種別と制約
- 05CLI と MCP によるアカウント確認
活用シーン
- 01ウェアラブルのライブデータを扱うアプリの構築
- 02バックエンドの WebSocket コンシューマー実装
- 03認証情報やユーザー接続の問題調査
MCP 対応
チャットアシスタントでアカウントを確認する際に、Terra API admin MCP サーバーを使う方法を説明します。MCP はプロデューサーまたはコンシューマー用の短期ソケットトークンを発行せず、トークンはバックエンドが発行します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tryterra/ agent-skills --skill terra-streamingインストール後、Claude Code で/terra-streamingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonREADME.mdreferences/android.mdconsumer-protocol.mddata-types.mdflutter.mdios.mdreact-native.mdwear-os.md詳細
Terra API Streaming のベストプラクティス
ウェアラブルからライブのメトリクスをおおむね毎秒配信する Terra API Streaming(リアルタイム)API を利用するアプリの構築ガイドです。このスキルには、アーキテクチャとプロトコル上の注意点が記載されています。プラットフォームの設定とコンシューマー向けプロトコルの全容は references/ にあります。
サンプルアプリから始める
新しいアプリを作る場合は、公開されているサンプルから始め、ユーザーの要件に合わせて調整します。React Native のプロデューサーには streaming-mobile-app、ウェブのコンシューマーには streaming-consumer-web-app を使用します。terra version を実行し、CLI が見つからない場合はインストールを提案します(下記を参照)。次に、現在のカタログを一覧表示して、最も適したものをクローンします。
terra examples list --select name,title,description
terra examples clone streaming-mobile-app my-app
どちらもログインは必要ありません。ダウンロードした README と AGENTS.md を読み、next_steps に従って依存関係をインストールし、設定してから実行し、それを土台に構築してください。クローンではファイルをダウンロードするだけです。既存のアプリの場合は、サンプルを参考にして関連する部分をその場で調整します。CLI を実行できないチャットアシスタントでは、ユーザー自身のターミナルで実行できる以下のコマンドを案内するか、ソースを https://github.com/tryterra/terra-examples/tree/main/examples/streaming-mobile-app で案内してください。
アカウントツール:CLI または MCP
ストリーミングの WebSocket API にはアカウントコマンドがなく、CLI も MCP も、ソケットの認証に使用するプロデューサートークンやコンシューマートークンを発行しません。これらは、このスキルで説明するフローを通じて、バックエンドがセッションごとに発行します。アカウントツールが扱うのは、その下位レイヤー、つまりバックエンドが保持する長期認証情報と、ストリーミング対象のユーザーが存在するかどうかです。
ストリームが開かない場合、多くは適切なスコープのない認証情報、接続情報のないユーザー ID、またはこの環境で有効になっていないプロバイダーが原因です。いずれも読み取り専用の確認なので、ソケットのデバッグに着手する前に実行してください。
terra environments list --select dev_id,name
terra data-tokens list --env <dev-id> --select token_id,name,scopes,expires_at,last_used_at,revoked_at
terra users list --env <dev-id> --user-id <uuid> --select user_id,provider,active
terra unified-api sources list --env <dev-id>
data-tokens list を使えば、秘密情報を表示せずに認証情報を確認できます。存在するトークン、それぞれのスコープ、期限切れや取り消しの有無が表示されます。トークンが機能するか確認するためにトークンを発行しないでください。また、ここで terra environments retrieve-api-key を使わないでください。環境の API キーと Webhook 署名シークレットが表示されますが、どちらもソケットの情報にはならず、CI ではその両方がジョブログに記録されます。
トークンの発行は診断ではなく、セットアップの手順です。一覧に利用可能なトークンが本当にない場合は、terra data-tokens create --env <dev-id> --name streaming --scopes auth:write を実行するとベアラートークンが返されます。環境ごとに複数のトークンを共存させられるため、取り消すまでは古いトークンも引き続き機能します。MCP 経由でデータトークンを発行するには、ダッシュボードでユーザーの承認が必要であり、デフォルトの MCP サインインでは許可されないアクセスレベルも必要です。そのため、この手順は CLI を使うほうが簡単です。
ユーザーのマシンまたはクラウド上のコーディングエージェント(Claude Code、Codex、Cursor など)では CLI を使用し、見つからない場合はインストールを提案します。macOS と Linux では curl -fsSL https://cli.tryterra.co/install.sh | sh、Windows PowerShell では irm "https://cli.tryterra.co/install.ps1" | iex を使います。ユーザーがすでに利用している場合は、Homebrew または npm でもインストールできます。チャットアシスタント(claude.ai、Claude Desktop、ChatGPT)では、コードを実行できる場合でも Terra API 管理用 MCP サーバーを使用します。サンドボックスでは CLI をインストールしたりサインインしたりできないためです。各管理コマンドは、ツール名と method によって表されます(terra users list は、method: "list" を指定した users_read です)。terra data-api、terra admin-api、terra examples を利用できるのは CLI のみで、--select と --jq に MCP の相当機能はありません。terra-cli と terra-mcp のスキルには、安全策(変更の確認、認証情報を会話履歴に残さないこと)、エラー、タスクごとの手順が記載されています。これらは連携を管理するものであり、このスキルで説明する API 呼び出しの代わりにはなりません。
ストリーミングとヘルス&フィットネス
ストリーミング API は、サブ秒から秒単位のリアルタイム信号専用です。RT SDK は 17 個の DataTypes 値を受け付けます。対象は、心臓関連(心拍数、HRV、RR 間隔、ECG)、動き(歩数、ケイデンス、距離、速度、階段の上昇階数、アクティビティ)、サイクリング(パワー、バイクのケイデンス)、モーションセンサー(加速度、ジャイロスコープ)、エネルギー(カロリー、MET)、位置情報です。列挙型の全項目については、references/data-types.md を参照してください。より長い期間に関するもの(ワークアウト、睡眠、1日の合計値、身体データ、栄養)は、ここではなく Unified API の対象です。ライブフィードではなく、完了したワークアウトの概要が必要な場合は、使用する API が異なります。Apple Health、Samsung Health、Health Connect を接続するには、Real-Time SDK ではなくモバイル SDK(terra-mobile-sdk)を使用します。
デバイスがストリームに表示されるのは、BLE、ANT+、またはサポート対象のカスタム Bluetooth プロトコルで実際にブロードキャストしている場合に限られます(Polar H10 や Wahoo TICKR などの心拍数ストラップ、一部のウォッチ)。ブロードキャストがなければ、ストリームもありません。
データ型をリクエストすることと、データを受信することは同じではありません。 Terra API はデバイスによる制限やフィルタリングを行いません。ブローカーはペイロードをそのまま中継するため、何が届くかはウェアラブル自体のブロードキャストプロファイルだけで決まります。ほとんどの心拍数ストラップは心臓関連のデータのみを送信し、SDK の設定にかかわらず STEPS や LOCATION を生成することはありません。データ型が欠けている場合にエラーとして扱うのではなく、信号ごとの状態を表示し、適切に機能を縮退させてください。詳しくは references/data-types.md を参照してください。
アーキテクチャ:プロデューサー、ブローカー、コンシューマー
リアルタイムストリーミングは 4 つの要素で構成され、それらの間に 3 つの接続を構築します。getting-started を参照してください。
- ウェアラブル – BLE または ANT+ でブロードキャストするストラップ、ウォッチ、センサーです。
- プロデューサー – Terra API Real-Time(RT)SDK を実行するモバイルアプリです。ウェアラブルのデータを受信し、Terra API に転送します。
- Terra API WebSocket ブローカー – ライブストリームをルーティングするサーバーです。Terra API のインフラストラクチャであり、ホストする必要はありません。
- コンシューマー – ブローカーに接続してストリームを受信するバックエンドです。
構築する 3 つの接続:
- ウェアラブルからアプリ:ユーザーが RT SDK を使い、Bluetooth/ANT+ 経由でウェアラブルをアプリにペアリングします。
- アプリからブローカー:アプリが プロデューサー 接続を開き、ウェアラブルのデータを転送します。
- ブローカーからバックエンド:バックエンドが コンシューマー 接続を開き、データをリアルタイムで受信します。
ユーザーの識別には、独自の reference_id を使用します。Terra API はそのユーザーに Terra API ユーザー ID を発行します(認証ウィジェットは不要です)。この ID は、トークンエンドポイントで使用され、すべてのペイロードの uid フィールドに含まれます。
トークン
すべての WebSocket 接続は、バックエンドが発行する短期間有効なトークンで認証されます。このトークンは、auth:write データトークン(Authorization: Bearer terra_dt_...)または環境の dev-id と x-api-key を使って発行します。3 種類のトークンはいずれも 1 回のみ使用できます。サーバーは IDENTIFY が成功すると各トークンを削除するため、再接続のたびに新しいトークンを発行する必要があります。開発環境でも本番環境でも、トークンを発行できる認証情報をアプリに含めないでください。サーバー側でトークンを発行し、そのトークンを引き渡してください。電話登録トークンを発行するためにバックエンドが保持する認証情報は、環境の API キーではなく、上記の「Account tools」から取得する auth:write データトークンです。
| トークン | エンドポイント | 使用元 | IDENTIFY の種類 |
|---|---|---|---|
| 電話登録 | POST https://api.tryterra.co/v2/auth/tokens | RT SDK の initConnection(電話をプロデューサーとして登録) | n/a(SDK が管理) |
| プロデューサー | POST https://ws.tryterra.co/auth/user?id=<terra_user_id> | データを送信するプロデューサー接続 | 0(USER) |
| コンシューマー/開発者 | POST https://ws.tryterra.co/auth/developer | バックエンドのコンシューマー | 1(DEVELOPER) |
ホストに注意してください。電話登録エンドポイントだけがメイン API(api.tryterra.co)上にあります。リファレンスファイルと提供済み SDK は、非推奨ながら同一の名前である /auth/generateAuthToken を呼び出しますが、新しいコードでは /auth/tokens を使用してください。プロデューサーとコンシューマーのトークンエンドポイントは WebSocket ホスト(ws.tryterra.co)から HTTPS 経由で提供され、api.tryterra.co には存在しません。リクエスト/レスポンスの正確なスキーマについては、リクエストを作成する際にREST エンドポイントのリファレンスを取得してください。
電話登録トークンは 1 回のみ使用でき、発行から3 分後に期限切れになります(expires_in として返されます)。そのため、アプリ起動時やキューに入れる前ではなく、アプリが initConnection を呼び出す直前に発行してください。プロデューサーエンドポイントには id クエリパラメーターで Terra API のユーザー ID を渡す必要があります。この ID は SDK の getUserId から取得してください。
WebSocket
両方のロールで使用するエンドポイントは 1 つです。wss://ws.tryterra.co/connect の IDENTIFY の type フィールド(0 はプロデューサー、1 はコンシューマー)によって、接続のロールが決まります。SDK はプロデューサー接続を開いて制御します。コンシューマー接続は、references/consumer-protocol.mdの手順を参考にして、自分で実装します。
このプロトコルはオペコードでフレームを構成します。HELLO とハートビートに続いて IDENTIFY と READY があり、その後 DISPATCH データペイロードが送られます。バックフィルには REPLAY を使用します(SUBMIT はプロデューサー側で使用され、SDK により抽象化されています)。オペコードの一覧と正確な JSON ペイロードの形式については、フレームを作成する際にterra-greater-than-your-backend.mdを取得してください。
プロトコル上の注意点
問題になりやすい点をまとめています。手順に沿ったコンシューマーの解説は、references/consumer-protocol.md をご覧ください。
- 接続後 15 秒以内に IDENTIFY してください。そうしないと、サーバーが 4000 で接続を閉じます。
- IDENTIFY が成功すると、トークンは削除されます。 接続が切断された場合、そのトークンは再利用できません。再接続する前に新しいトークンを発行してください。
- ハートビート。 HELLO には
heartbeat_interval(ミリ秒)が含まれます。最初のハートビートはheartbeat_interval * jitter(jitter は 0〜1 のランダム値)の後に送信し、その後は各間隔につき最大 1 回送信してください。HEARTBEAT_ACK が届かない場合は、接続を閉じて再接続してください。サーバーが規定時間内にハートビートを受信しないと、4005 で接続を閉じます。 - クローズコードは 2 つのグループに分かれます。 4000、4003、4004、1003 はクライアントのバグを示します。クライアントを修正し、再接続を繰り返さないでください。無条件に再接続しても同じエラーが繰り返されるだけです。4001 の場合は、新しいトークンを発行してください。4002 は、サーバーのコンシューマーセッション上限により接続が拒否されたことを意味します。同時に接続できるコンシューマー数に保証された値があることを前提に設計しないでください。4002 が発生した場合は、既存のセッションを閉じるか、再接続を繰り返さずにバックオフしてください。
seqは単調増加しますが、連続しているとは限りません。 連続するシーケンス番号の間にギャップがあるのは正常で、データの損失を意味しません。seqは DISPATCH の順序付けと、リプレイのafter境界としてのみ使用してください。- REPLAY の境界は排他的です。両方を指定してください。
afterとbeforeはどちらも必須です。beforeを省略した REPLAY はメッセージを返しません。再接続時は、afterに最後に処理したseqを、beforeに最初のライブ DISPATCH のseqを設定し、欠落した範囲を正確に補完してください。 - リプレイには数秒の遅延があります。 ペイロードは、ライブ配信された数秒後にリプレイ可能になります。REPLAY で期待した数より少ないメッセージが返された場合は、少し待ってから再度リクエストしてください。
- ハードウェアなしでテストできます。 Terra API ダッシュボード の Streaming ページでテストユーザーを作成してください。Terra API は実際の API 経由で合成ライブデータをストリーミングするため、デバイスを使う前にコンシューマーをエンドツーエンドで検証できます。
- アプリを開くたび、またはフォアグラウンドに戻すたびに RT SDK を再初期化してください。 プロデューサーの登録は、アプリがバックグラウンドになると維持されません。
- Apple Watch は、ワークアウトセッション外では記録頻度が低下します。 最も高い頻度でデータを記録するには、Apple Watch でワークアウトセッションを開始してください。
リファレンス
構築する対象に応じたリファレンスをお読みください。
- references/consumer-protocol.md – バックエンドのコンシューマーを作成する前にお読みください。 ハンドシェイクの手順(HELLO、ハートビート、IDENTIFY、READY、DISPATCH)、DISPATCH のフィールドの意味、REPLAY でバックフィルする方法、クローズコードの処理を説明し、正確なペイロード形式を確認できる最新ドキュメントへのリンクも掲載しています。
- references/data-types.md – RT SDK でリクエストするデータを選ぶときや、ストリームが無反応なときにお読みください。
DataTypesとConnectionsの全 enum、リクエストしても受信できるとは限らない理由、Wear OS のエクササイズ接頭辞付きのタイプラベルを説明しています。 - references/ios.md – プロデューサーアプリがネイティブ iOS の場合や、Apple Watch を接続する場合にお読みください。Apple Developer Program のメンバーシップが必要です。
- references/android.md – ANT+ やプログラムによるデバイススキャンを含め、プロデューサーアプリがネイティブ Android の場合にお読みください。
- references/react-native.md – プロデューサーアプリが React Native の場合にお読みください。
- references/flutter.md – プロデューサーアプリが Flutter の場合にお読みください(
startRealtimeToAppとstartRealtimeToServerの違いに注意)。 - references/wear-os.md – Android スマートフォンとペアリングした Wear OS ウォッチからストリーミングする場合にお読みください。
全ドキュメント:docs.tryterra.co/streaming-api。ページを取得する前に terra docs ask(または MCP 経由の docs_ask)を実行してください。ドキュメントに基づいて回答し、出典を引用します。ドキュメントの URL の末尾に .md を追加すると、Markdown 形式で取得できます。
ご自身で決める事項
ドキュメントでは意図的に以下を未指定にしています。デフォルトを前提とせず、アプリに合ったものを選んでください。
- ストリーミングするデータ型。 SDK に型のセットを渡し、使用するものだけをストリーミングします。
- デバイススキャンのキャッシュ。
useCacheやshowWidgetIfCacheNotFound(Android)などのフラグを使うと、既知のデバイスへの再接続を速くする代わりに、常にピッカーを表示する動作にはなりません。 - ローカルのみのストリーミングとサーバーへのストリーミング。 アプリへのローカルストリーミングとブローカーへのストリーミングは、別々に選択できます。Flutter ではこの違いが明示されており、
startRealtimeToApp(ローカルコールバックのみ)とstartRealtimeToServer(ブローカーのみ)を使います。他のプラットフォームでは、トークンを渡すと同じstartRealtime呼び出しでブローカーにストリーミングします。 - トークンの受け渡し。 アプリがバックエンドからプロデューサートークンを取得する方法(エンドポイントの形式、認証)は任意です。
- 再接続とバックフィルの戦略。 どの程度積極的に再接続するか、切断のたびに再生するか、最後に処理した
seqをどのように永続化するかは、自由に決められます。 - コンシューマーの構成。 1 つのコンシューマーから内部で処理を分配するか、複数のコンシューマーを使うかは、セッション上限の範囲内でアーキテクチャに応じて決めてください。
reference_idの方式。reference_idを独自のシステム内の何に対応させるかは、自由に決められます。