terra-lab-reports について
Terra API Lab Reportsとの連携を構築する開発者向けスキルです。臨床検査レポートからバイオマーカーを抽出・標準化するプレリリースサービスについて、APIのワークフロー、データの意味、実装方法を説明します。
主な機能
- 01臨床レポートのOCRとAI抽出
- 02バイオマーカーの照合と標準化
- 03非同期処理とステータス管理
- 04RESTエンドポイントとWebhookのガイド
- 05セッション、結果、配信のトラブル調査
活用シーン
- 01臨床レポートのアップロード処理を構築
- 02標準化済みバイオマーカー結果を取得
- 03レポートの配信や処理状態を調査
MCP 対応
チャットアシスタントで管理コマンドを実行するため、Terra API admin MCPサーバーを利用する方法を説明します。ここで説明するMCPツールでは検査レポートのセッションエンドポイントを扱えないため、CLIのterra data-apiまたはアプリケーションコードが必要です。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tryterra/ agent-skills --skill terra-lab-reportsインストール後、Claude Code で/terra-lab-reportsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonREADME.mdreferences/api-reference.mdbiomarkers.mdwebhook-payload.mdrules/_sections.md_template.mdapi-poll-at-most-every-5s.mdapi-space-bulk-uploads.mddata-filter-ranges-by-demographics.mddata-keep-unmatched-biomarkers.mddata-parse-utf8.mddata-store-ids-as-strings.mdwebhooks-dedupe-event-id.md詳細
Terra API Lab Reports のベストプラクティス
Terra API Lab Reports(プレリリース)を使った開発のための、本番環境向けガイドラインと API リファレンスです。臨床検査レポートの PDF や画像を、構造化された標準化済みのバイオマーカーデータに変換します。OCR と AI による抽出を行い、次に 4,000 件以上のバイオマーカーを含む参照データセットとファジーマッチングを行うことで、正規のバイオマーカーキー、UCUM 単位コード、LOINC コードを取得します。
プレリリース:仕様が変更される可能性があるものとして扱ってください。 本番用のリクエストボディや Webhook パーサーを生成する前に、最新のドキュメントページを取得し、リリース前に最新の API で検証してください。
サンプルアプリから始める
新しいアプリを作る場合は、検査レポートのアップロードとバイオマーカーの推移に関する公開済みのサンプルから始め、ユーザーの要件に合わせて調整してください。terra version を実行し、CLI が見つからない場合はインストールを案内してください(以下を参照)。次に、現在のカタログを一覧表示し、最も適したサンプルをクローンします。
terra examples list --select name,title,description
terra examples clone lab-reports-web-app my-app
どちらもログインは不要です。ダウンロードした README と AGENTS.md を読み、next_steps に従って依存関係をインストールし、設定して実行してから、その上に構築してください。クローンでダウンロードされるのはファイルのみです。既存のアプリの場合は、サンプルを参考にして、関連する部分をその場で調整してください。CLI を実行できないチャットアシスタントの場合は、ユーザー自身のターミナルで実行するコマンドを案内するか、ソース(https://github.com/tryterra/terra-examples/tree/main/examples/lab-reports-web-app)へのリンクを提示してください。
アカウントツール:CLI または MCP
すべての Lab Reports エンドポイントには手動でアクセスできます。「あのレポートはどこに行ったのか」という疑問に答えるには、これが最も手早い方法です。
terra data-api /lab-reports -q reference_id=<ref>
terra data-api /lab-reports/<session_id> # status and parsed results
terra data-api /lab-reports/<session_id>/deliveries # per destination: status, attempts, last error
terra data-api /lab-reports/<session_id>/files # the input files behind the session
レポートが解析されたのに届かなかった場合、最初に使うべきなのは deliveries です。「配信されなかった」のか、「配信されたがエンドポイントに拒否された」のかを区別できます。この2つは異なる不具合です。1回のアップロードが複数のセッションに分岐する場合があるため、1回のアップロードにつきセッションは1つだと思い込まず、Webhook イベントまたは /lab-reports?upload_id=... からセッション ID を確認してください。
エンドポイントが受け取る内容は、terra admin-api list --data-api /lab-reports --format json で確認できます。
上記の各コマンドは terra data-api です。これは CLI でのみ使えます。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 呼び出しに代わるものではありません。
プロダクトの機能
臨床検査レポートをアップロードすると、構造化されたバイオマーカーの結果を受け取れます。結果は抽出・標準化され、指定した送信先に配信されるか、REST 経由で利用できます。
- 入力: リクエストごとに1ファイル。PDF、PNG、JPEG、GIF、WebP に対応し、ファイルサイズは最大20 MBです。
- 抽出: OCR と AI による解析で、各結果の名称、値、単位、フラグ、基準範囲をページから抽出します。
- 標準化: 抽出した各名称を、4,000件以上の項目を含むバイオマーカーデータセットとファジーマッチング(しきい値0.85)し、標準バイオマーカーキー、UCUM 準拠の
ucum_code、さらに LOINC に対応する項目についてはloinc_codeを生成します。 - 出力: レポート単位のパネルにグループ化された、階層構造の結果(source / biomarker / measurement / interpretation / reference ranges)を含むセッションを、
lab_report.completedイベント(または最終的な失敗時にはlab_report.failed)として配信します。
非同期ワークフローとステータスのライフサイクル
処理は完全に非同期です。アップロードは 202 と upload_id(current_status: "processing")を直ちに返し、レポートは次の状態をたどります。
processing → processed → standardizing → standardized → sending → sent
その他のステータス:retry_scheduled、retrying、cancelled、deleted、failed。最終状態は sent、failed、cancelled、deleted です。
セッションが standardized になると、配信前でも結果を照会できます。 結果を読むために sent まで待つ必要はありません。Webhook イベント(成功時は lab_report.completed、最終的な失敗時は lab_report.failed)またはポーリングで結果を確認できます。通常、処理には30秒から3分かかります。
エンドポイント
ベース URL は https://access.tryterra.co/api です。すべてのリクエストで、dev-id と x-api-key の両方のヘッダーが必要です。
| メソッド | エンドポイント | 備考 |
|---|---|---|
| POST | /v2/lab-reports | マルチパートでアップロードします。フィールド名は必ず file(単数形)とし、1 リクエストにつき 1 ファイルを指定します。202 を返すと、upload_id と current_status: "processing" が返されます。session_id は返されません(1 回のアップロードから複数のセッションに振り分けられることがあります)。 |
| GET | /v2/lab-reports | 一覧表示/フィルタリング(reference_id、upload_id、report_date_from/_to、uploaded_at_from/_to による)。上限は 500 件です。フィルターを使用してください。 |
| GET | /v2/lab-reports/{session_id} | セッション:メタデータ、upload_id、ステータス履歴、階層化された results[]、panels[]。ファイル、成果物、配信状態は埋め込まれません。サブリソースを使用してください。 |
| GET | /v2/lab-reports/{session_id}/files | 入力ファイルとサムネイルを、レスポンスレベルの expires_at とともに署名付き URL として返します。 |
| GET | /v2/lab-reports/{session_id}/deliveries | 配信先ごとの配信状態(destination_id、status、attempt_count、last_error)。 |
| GET | /v2/lab-reports/{session_id}/artifacts | 処理成果物。特権キーのみ利用できます。標準キーでは 404 が返されます。 |
| POST | /v2/lab-reports/{session_id}/reprocess | 抽出/標準化を再実行します。非同期で 202 が返されます。同じ session_id で新しいイベント(新しい event_id)が発行されます。 |
| DELETE | /v2/lab-reports/{session_id} | ソフト削除します。204 が返されます。 |
references/api-reference.md では、各目的に対応するエンドポイントと、仕様ページでは詳しく説明されていない動作を確認できます。エンドポイント呼び出しを実装する前にお読みください。リクエスト/レスポンス/エラーの完全な仕様(RFC 7807 の形式、ステータスコード)については、呼び出しを実装する際に最新のページを取得してください:API Reference(Markdown 版は .md を末尾に追加します)。
データモデル
階層構造:Session → Results[] + Panels[]。各 Result は複数のレイヤーで構成されます。
- Session –
session_id(snowflake 文字列)、upload_id、任意のreference_id、current_status、report_type、レポート日時/採取日時、report_locale、lab_name、patient_sex、patient_age_at_collection、status_history[]、results_count、file_count、input_bytes、output_bytes、report_notes、results[]、panels[]。 - Panel – レポート単位のグループ化:
{ id, name, key }。Results はbiomarker.panel_idを介してこれを参照します。 - Result – 次の 4 つのレイヤーで構成され、webhook ペイロードと GET で同一です。
source– レポートに文字どおり記載された内容:name、panel、value(未加工の文字列)、units、flag(原文どおり)、method、notes、reference_text(webhook 側のコピーにのみcollection_date/collection_timeも含まれます。GET ではこれらは session に含まれます)。biomarker– 正規化された識別情報:key(一致しない場合は null)、display_name、loinc_code、panel_id、panel_key、specimen。measurement– 型付きの値:typeは値が格納されている兄弟フィールドを示します(numeric、bounded{operator, value}、qualitative{text, code}、text、またはabsent_reasonを伴い省略)。さらにunitsとucum_codeが含まれます。interpretation– 異常値のレイヤー:flag(コード化され、null の場合があります)、flag_raw、source、applied_range{lower, upper}(flag の判定に使用された範囲)。
- Reference Range –
lower、upper、type(判定結果ではなく、範囲の種類を表すラベル)、およびcontext(sex、age_lower/age_upper、pregnancy_status、cycle_phase、gestational_week_lower/_upper、reference_population、modifiers[])。
Webhook のエンベロープの仕様についてはreferences/webhook-payload.mdを参照してください。フィールドごとの型と列挙値の表(値は固定されておらず、今後追加されます)については、Core Concepts の最新ページを取得してください(Markdown 版は末尾に .md を付けてください)。
重要なデータ仕様
biomarker.keyは、一致しない場合もフィールドとして存在し、値は NULL です – これが一致しないことを示す唯一のシグナルです。loinc_codeを判定に使用しないでください(一致している場合でも null のことがあります)。source.name/biomarker.display_nameを代わりに使用し、結果は保持してください。measurement.typeに基づいて分岐し、対応するフィールドを読み取ってください。 複数の値フィールドを優先順位に沿って調べないでください。フラットなvalue/value_gt/value_lt/qualitative_valueフィールドは廃止されています。<0.5のような上限値はbounded: { "operator": "lt", "value": 0.5 }として届きます。- 2 種類の flag には、異なる意味があります。
source.flagは検査機関の未加工文字列("H"、"↑"など)です。interpretation.flagはコード化されたシグナル(null の場合があり、null はシグナルがないことを意味します)で、flag_rawが原文どおりの形式を示し、sourceがその由来を示します。 - 列挙値は固定されていません。
current_status、report_type、measurement.type、specimen、範囲のtype、patient_sexには、メジャーバージョンの更新なしで新しい値が追加される場合があります。不明な値は適切に処理してください(既定/不明のカテゴリを使用し、例外を発生させないでください)。 - すべての列挙値は小文字の文字列です(
"REPORT_STATUS_SENT"や6ではなく"sent")。すべてのタイムスタンプは ISO-8601 UTC 形式です。
注意点
- アップロード時に返されるのは
upload_idであり、session_idではありません。202の本文は{ "upload_id": "...", "current_status": "processing" }です。1 回のアップロードから複数のセッションが作成されることがあります。セッション ID は Webhook のdata.session_idまたはGET /v2/lab-reports?upload_id=...で取得してください。古いセッションではupload_idがない場合があります。任意項目として扱ってください。 - Webhook イベントは 2 種類あります。エンベロープの
typeで分岐してください。 成功時はlab_report.completed、最終的な失敗時はlab_report.failedです。宛先ごとのオプトインでは、引き続きdestination_event_typesに単一の汎用タイプ"lab_report"を使用します。どちらのイベントもこれを共有します。 event_idで重複を排除してください。 同じ保存済みペイロードの再配信では、同じevent_idが引き継がれます。再処理では新しいevent_idが発行され、session_idは同じです。rules/webhooks-dedupe-event-id.md を参照してください。- 失敗には構造化されたエラーが含まれます。
data.errorは{ code, message, retriable }で、コードはfile_unreadable、extraction_failed、standardization_failed、internalです。retriable: trueは、同じ入力を再送信すると成功する可能性があることを意味します。falseの場合は、まず入力を修正してください。 reference_rangesが設定されていても、interpretation.applied_rangeが null の場合があります。 患者に適用される範囲を曖昧さなく 1 つに特定できる場合にのみ設定されます。null の場合は、コンテキストに基づいてreference_rangesを自分でフィルタリングしてください(rules/data-filter-ranges-by-demographics.md を参照)。- 署名付きファイル URL はサブリソースにあり、有効期限があります。
GET .../files(および権限が必要な.../artifacts)は、レスポンスレベルのexpires_atを含む署名付き URL を返します(有効期限はおよそ 1 時間後です)。これらの URL は Webhook やセッションのレスポンスには埋め込まれません。再発行するには、サブリソースを再取得してください。expires_atを過ぎた URL は保存しないでください。 - アーティファクトの取得には権限が必要です。権限がない場合は
404になります。 標準キーでGET .../artifactsを呼び出すと、空のリストではなく404が返されます。 - サイズ超過のアップロード: 20 MB を超えるファイルは、バイト数制限リーダーにより通常、
400(「invalid multipart form or file too large」)で拒否されます。413が発生するのは、multipart のパートで Content-Length が上限を超えている場合のみです。400が返されることを想定してください(場合によっては413)。
ルール
コードを書く前に、rules/ にある該当するルールを読んでください。各ファイルは単独で参照でき、誤った例と正しい例が記載されています。
Webhook と配信(高)
webhooks-dedupe-event-id–event_idを冪等性キーにしてください。再配信では同じ ID が再利用され、再処理では同じsession_idのまま新しい ID が発行されます。api-poll-at-most-every-5s– 本番環境では Webhook(成功イベントと失敗イベントの両方)、開発環境やフォールバックではポーリングを使用してください。ポーリングの間隔は 5 秒以上とし、終端状態になったら停止してください。
データ処理と API の使用(高〜中)
data-keep-unmatched-biomarkers–biomarker.keyが null の場合も臨床的に重要です。結果を破棄せず、source.nameにフォールバックし、確認が必要であることを示してください。data-filter-ranges-by-demographics–interpretation.applied_rangeがある場合はそれを使用してください。ない場合は、解釈の前に性別・年齢・コンテキストに基づいてreference_rangesをフィルタリングし、measurement.boundedは慎重に扱ってください。data-store-ids-as-strings– Snowflake のsession_idは JavaScript の数値にすると精度が失われます。最初から最後まで文字列として保持してください。data-parse-utf8– データにはµ、×、±、上付き文字が含まれます。必ず UTF-8 として解析してください。api-space-bulk-uploads– 1 リクエストにつき 1 ファイル、上限は 20 MB、所要時間はファイルあたり 30 秒〜3 分です。複数ファイルを一括アップロードする場合は間隔を空け、reference_idを付けてください。
参考資料
詳細な仕様を確認するには、以下を読み込んでください(各資料は単独で利用できます)。
- references/api-reference.md – 目的からエンドポイントへのルーティングと、仕様ページでは詳しく扱われていないセマンティクスを説明しています。エンドポイントを呼び出す前に読み、リクエスト/レスポンスの全体像を確認するには、リンク先のライブページを取得してください。
- references/webhook-payload.md – イベントエンベロープ(
type、event_id、occurred_at、upload_id、data)、冪等性キー、失敗イベントについて説明しています。Webhook ハンドラーの構築時にお読みください。 - references/biomarkers.md – 標準化、UCUM マッピング、LOINC の対応範囲、カテゴリ別の一般的なバイオマーカーの表について説明しています。キー、単位、LOINC コードを扱う際にお読みください。
バイオマーカーの全データセット(4,000 件以上、約 700 KB)は同梱されていません。バイオマーカーリファレンスページからダウンロードしてください。
ライブドキュメント
ページを取得する前に terra docs ask(または MCP 経由の docs_ask)を使ってください。ドキュメントに基づいて回答し、出典を示します。ドキュメントの URL に .md を追加すると、Markdown 形式で取得できます。