統合データAPI入門:機能カタログから最初の有効な結果を得るまで
platform、action、paramsで複数プラットフォームのデータにアクセスします。機能カタログの読み方、最小限のリクエストの送信、非同期タスク・部分的な結果・課金の扱い方、追跡可能なデータ記録の作り方を解説します。
1つのプラットフォーム向けにリクエストコードを書くのは、たいてい難しくありません。本当に手間がかかるのは2つ目のプラットフォームが加わったときです。パラメータ名が変わり、ユーザーやコンテンツの識別子も異なり、すぐにデータを返すエンドポイントもあれば、先にタスクを作成するものもあります。cronジョブが動き始めると、リトライ、重複排除、課金の照合がそれぞれ別々のコードパスとして増えていきます。
統合データAPIは、こうした重複した統合の手間を解消します。EveryInfraのEveryDataでは、同じBearer認証を使い、platformでプラットフォームを、actionで機能を選び、機能固有のパラメータをparamsで渡します。統一されているのは呼び出しの入口と共通の処理フローであり、すべてのプラットフォームのデータを1つの業務オブジェクトに無理にそろえるわけではありません。
このチュートリアルでは、Xiaohongshuのノート検索を使った最小限のリクエストを示し、ほかの機能へ広げる方法を説明します。目的は1回のHTTPリクエストを実行することだけではありません。どのデータを取得したか、どの結果が保留中か、次の実行でその差をどう埋めるかを、プログラムが把握できるようにすることです。例は2026-09-04時点で検証した公開カタログと実装に基づいています。本番環境向けのPOSTスニペットは、許可されたシナリオで使用する呼び出しテンプレートであり、新たに実環境で成功を確認した例ではありません。
最初の判断:必要なのはデータ取得か、検索と生成か
特定のノート、商品、場所など、対象が属するプラットフォームがすでにわかっていて、その構造化されたフィールドを読み取りたい場合は、データAPIから始めるのが適切です。素材がオンラインのどこにあるかをまだ探している段階なら、まずWeb検索を実行してください。素材が手元にあり、要約、分類、レポート作成が必要な場合は、モデルで処理します。
コメント分析を例にすると、収集ではコメントの内容と出所を確認し、モデルではテキスト内にどのような問題があるかを判断します。モデルは、収集の失敗で欠けたレコードを作り出すことも、返されなかったコメント数をゼロと解釈することもできません。この2つのフェーズを分けておけば、結論に異論が出たときに呼び出しチェーン全体を推測し直すことなく、元の根拠に立ち戻れます。
ステップ1:プラットフォーム名からエンドポイントを推測せず、カタログで機能を確認
機能カタログはAPIキーなしで読み取れます。まずコンパクト版で利用可能なプラットフォームとアクションを把握し、次に選んだプラットフォームのパラメータとフィールドの完全なリファレンスを取得します。コンパクト版は機能の探索用で、パラメータとフィールドの説明は省略されています。簡易カタログを完全なリクエストバリデーターとして扱わないでください。
curl -fsS --max-time 30 \
'https://api.everyinfra.com/api/v1/social/catalog?compact=1' \
| jq '.capabilities[] | {platform, action, required_params, mode, available}'たとえば、調査キーワードに関連するXiaohongshuのノートを探すなら、まずsearchを確認します。ノートのリンクがすでにあり、詳細やコメントを取得したい場合は、それぞれnoteまたはcommentsを選びます。名前が似ていても互換性があるわけではありません。検索キーワードを詳細リクエストのURLとしてそのまま渡すことはできません。
curl -fsS --max-time 30 \
'https://api.everyinfra.com/api/v1/social/catalog?platform=xiaohongshu' \
| jq -e '.capabilities[] | select(.action == "search") | {
platform, action, required_params, optional_params,
param_meanings, mode, returns_list,
default_limit, max_limit, response_fields, available
}'今回のカタログ検証では、xiaohongshu.searchの必須パラメータはkeywordで、modeはsync、returns_listはtrueでした。デフォルトの件数は20、上限は50です。この2つはこの機能の件数設定を示すもので、リクエストごとの取得件数の保証や、プラットフォーム共通の上限ではありません。カタログにはsortとcontent_typeも記載されています。絞り込む際はparam_meaningsに記載された許可値を使い、ほかのプラットフォームの列挙値を流用しないでください。
- required_params:必須の入力です。まずこれらを満たし、そのうえでフィルターを少しずつ追加してください。
- param_meanings:パラメータの定義と、宣言された許可値です。記載されていないフィールドに独自の列挙値を作らないでください。
- modeとreturns_list:タスクのポーリングが必要かどうかと、最終的に返されるデータがリストか単一オブジェクトかを示します。
- response_fields:フィールドのマッピングを計画するためのものです。実際のレスポンスではなく、すべてのフィールドに値が入っていることを保証するものでもありません。
- available:カタログ上の利用可否フラグです。対象URLが今すぐデータを返すことを事前に保証するものではありません。
リスト系の機能は汎用の件数上限にも対応していますが、これはoptional_params内に重複して記載されない場合があります。この区別はリクエスト検証コードで確認済みです。統合時は、リストかどうかの宣言、デフォルト値と上限、完全な説明をあわせて確認してください。optional_paramsとの文字列照合だけを根拠に、有効な上限パラメータを削除しないでください。
ステップ2:容易に確認できる規模のリクエストを送信
適切な機能権限を持つAPIキーを用意し、サーバーの環境変数経由で渡してください。ブラウザのフロントエンドコード、スクリーンショット、公開ダウンロード用のサンプルファイルには含めないでください。以下の例では、EVERYINFRA_API_KEYを独自のシークレット管理で設定済みであることを前提とします。コマンドは1回だけリクエストを送信し、自動リトライは行いません。
: "${EVERYINFRA_API_KEY:?set the server-side API Key first}"
curl --silent --show-error --include --max-time 180 \
'https://api.everyinfra.com/api/v1/social' \
-H "Authorization: Bearer ${EVERYINFRA_API_KEY}" \
-H 'Content-Type: application/json' \
--data '{
"platform": "xiaohongshu",
"action": "search",
"params": {
"keyword": "AI tools",
"limit": 5
}
}'ここでの5は目標とする小さなサンプル数で、取得件数の保証ではありません。180秒はこの例でのクライアント側の待機タイムアウトで、サービスのSLAではありません。件数を増やす前に、少数の結果でフィールド、タイムスタンプの形式、ソースのリンクを確認してください。初期のデバッグではHTTPステータス行とレスポンスボディを残しておくと、4xxや5xxが返ったときに、curlの汎用的な失敗メッセージではなく具体的なエラーを読み取れます。
3つのトップレベルフィールドは区別して扱います。platformとactionで機能を選び、業務上の条件はすべてparamsに入れます。keywordをトップレベルに出したり、page、cursor、sortをサポートしていないアクションに付けたりしないでください。カタログにないパラメータは、多くのAPIがそう設計されているからといって、サポートされているとみなすことはできません。
OpenAPIは、リクエストボディ、パラメータ、レスポンスを人とプログラムが記述するのに役立ちますが、プラットフォーム間で同一の業務モデルを義務づけるものではありません。型の生成や呼び出し側の実装では、仕様を使ってインターフェース記述の形式を理解し、正確なフィールドはサービス自身のカタログとレスポンス形式で判断してください。
ステップ3:同期結果の外側と内側の構造を把握
選択したxiaohongshu.searchでは、実装上、リストはresultsの中に格納され、その外側にid、platform、action、count、billing、quotaなどのメタデータが置かれます。外側のidはリクエストの追跡用識別子で、results内の各レコードのidはコンテンツの識別子です。この2つを混同しないでください。前者はデバッグや照合に、後者はレコードの重複排除に使います。
resultsを、すべてのクライアントで唯一の取得経路とみなさないでください。ほかのアクションでは、別の名前でビジネスオブジェクトが返される場合があります。returns_listはオブジェクトの形を示し、フィールド辞書は内部フィールドを説明しますが、どちらも選択した機能の外側の構造を確認する作業の代わりにはなりません。新しい機能を追加するときは、すべてのレスポンスを再帰的に探索して最初の配列を拾うのではなく、結果変換用の明確な設定を用意してください。
curl -fsS --max-time 30 \
'https://api.everyinfra.com/api/v1/social/fields?platform=xiaohongshu&action=search' \
| jq '{fields, undocumented}'フィールドの扱いで結論を左右しやすい点が2つあります。第1に、エンゲージメント指標がnullの場合は非公開または取得できないデータを意味するため、平均を計算する前に自動で0で埋めないでください。第2に、posted_atの公開ドキュメントでは、プラットフォームの生のタイムスタンプ文字列をそのまま保持することが認められています。すべての値がそのまま単一のISO形式にパースできると想定しないでください。パース済みのタイムスタンプは別に保存し、パースに失敗した日付を今日の日付で埋めるのではなく、失敗を示すステータスフラグを残してください。
レスポンスにpartialやmissedのフラグが含まれる場合、取得できなかったターゲットは別途追跡する必要があります。HTTP 200は、バッチ内のすべてのターゲットでデータが得られたことを保証しません。空の配列から正しく言えるのは「今回はレコードが返されなかった」ということだけで、元のプラットフォームにデータが存在しないという意味ではありません。リクエストが正しい対象をカバーし、範囲の制限を守っていたかどうかは、別の問題です。
ステップ4:非同期機能ではjob_idで止めず、終了状態まで待機
modeがasyncの機能に切り替えると、送信時のレスポンスとしてHTTP 202とともにstatus、job_id、poll_urlが返される場合があります。タスクの照会を始める前に、これらのフィールドを永続化してください。HTTP仕様では、202はリクエストが受理されたものの処理が完了していないことを示します。「レポート生成完了」のようなビジネス通知のトリガーには使わないでください。
: "${EVERYINFRA_API_KEY:?set the API Key used for this task first: API Key}"
: "${EVERYINFRA_JOB_ID:?paste the job_id from the actual submit response}"
curl --silent --show-error --include --max-time 30 \
"https://api.everyinfra.com/api/v1/jobs/${EVERYINFRA_JOB_ID}" \
-H "Authorization: Bearer ${EVERYINFRA_API_KEY}"現在の照会の実装では、送信時に使用したAPIキーをもとにジョブを検索します。同じAPIキーで照会してください。同じアカウント内でAPIキーを切り替えてもタスクを取得できるとは考えないでください。見つからない場合も、すぐに同じタスクを作り直さないでください。APIのドメイン、job_id、使用したAPIキーを確認し、必要に応じて保存しておいたリクエスト情報を参照してください。
- runningまたはfinalizing:処理中の状態です。タスクを保持し、ポーリング間隔に上限を設けて照会を続けます。
- succeeded:タスクが成功を示す終了状態に達したことを表します。機能のデータオブジェクトをパースし、ビジネス要件を満たしているか確認します。
- failed:タスクが失敗を示す終了状態に達したことを表します。errorを読み取り、空データで正常終了したものとして扱わずに、タスクの記録を保持します。
- 照会のタイムアウトまたは不明なステータス:「未確認」としてのみマークします。後続のリカバリー処理に向けて合計の待機時間の上限を設定し、成功や失敗に書き換えないでください。
ポーリング処理には最大待機時間を設け、間隔を徐々に延ばすバックオフによってタイトなループを防いでください。プログラムの再起動後は、タスクを再送信せず、保存したjob_idsを使ってポーリングを再開します。送信時のbillingは別に保存してください。現在の結果照会レスポンスには完全なbillingブロックが再度含まれないため、照会結果にbillingがなくても課金がゼロとは限りません。
Microsoftの非同期要求-応答パターンも、受理、ステータス確認、最終結果を分離し、ポーリングのヒントについても説明しています。クライアントのワークフロー設計の参考になります。ただし、LocationやRetry-Afterなどのヘッダーは、ここではEveryInfraが返すことを保証するものではありません。実際の照会には、引き続き現在のレスポンスで示されたエントリーポイントを使用してください。
ステップ5:根本原因に応じたエラー対応、特にPOSTの安易な再試行の回避
ビジネスエラーでは、HTTPステータスとerror.codeを同時に確認する必要があります。現在のデータエントリーポイントでは、まず認証を確認し、次に機能、権限、パラメータを確認してから、クォータ確認と実行のフローに進みます。有効なAPIキーがない状態で401が返っても、業務処理用のパラメータが検証を通過したことにはなりません。
- 401:APIキーが存在し有効であること、Bearerヘッダーが正しいことを確認します。キーワードを変更して認証エラーを直そうとしないでください。
- 403:APIキーに対象のプロダクトと機能の権限があるか確認します。権限の問題は権限を持つ担当者が対応し、アカウントを自動で切り替えないでください。
- 400 unknown_capability:プラットフォームとアクションの組み合わせを確認します。カタログを読み直し、サービスが提示する候補名を確認してください。
- 422:必須項目、不明なパラメータ、不正なenum値を確認します。新しいリクエストを送る前に、示されたエラーを1つずつ修正してください。
- 402:クォータ不足です。アカウントのクレジットの問題を解決する必要があります。同じリクエストを繰り返しても結果は変わりません。
- 429、一時的なサービスエラー、またはネットワーク切断:バックオフし、元のリクエストの状態を確認します。再試行しても安全であることを確認できた場合に限り、回数に上限を設けて再試行してください。
最も見落としやすいのは、クライアント側でタイムアウトしても、サーバー側ではすでにリクエストを受理している可能性がある点です。データ取得はビジネス上は読み取り専用に見えますが、POSTで実行されるため、タスクが作成され、課金が発生する場合があります。相関IDは複数回の試行を関連付けるのに役立ちますが、サーバー側の冪等性を自動で保証するものではありません。APIが明示的にサポートしていないIdempotency-Keyヘッダーを追加しただけで、重複リクエストが1回しか実行されないと想定しないでください。
RFC 9110は、非冪等なリクエストの自動再試行に厳しい制限を設けています。このように結果が不明な場合は、まず既存のタスクを照会するか、リクエストの記録を確認してください。情報が足りないときは、バッチ全体を自動で再実行するより、不明なステータスのまま保持するほうが安全です。
ステップ6:データ、収集ステータス、課金の個別保存
統一されたエントリーポイントの最大の利点は、汎用的な記録とプラットフォームごとのフィールドマッピングの役割分担が明確になることです。少なくとも、ビジネスタスク、APIの試行、プラットフォームオブジェクトの3種類の記録を管理してください。これにより、1つのタスクで何回試行したかを追跡でき、同じコンテンツを複数回収集しても、重複したオブジェクトを新たに作らずに更新できます。
- タスクの記録:独自のtask_id、対象範囲、期待するフィールド、完了条件。ここでの完了はビジネス上の定義によるもので、HTTPの成功だけを指すわけではありません。
- リクエストの記録:プラットフォーム、アクション、機密情報を含まないパラメータの概要、開始・終了時刻、APIリクエストID、job_ids、status、billing。失敗した試行も残してください。
- オブジェクトの記録:プラットフォーム、オブジェクトの種類、オブジェクトID、ソースリンク、実際に取得したフィールド、observed_at。異なるプラットフォーム間でIDが偶然一致しても統合しないでください。
これらはアプリケーションのデータモデルとしての推奨事項で、EveryInfraが追加で返すフィールドではありません。observed_atは収集側で記録して観測時刻を表し、posted_atは元のコンテンツの公開時刻を示します。両方を使うと、コンテンツがいつ公開されたかと、こちらがいつそれを把握したかを区別でき、データの遅延や繰り返しの観測を分析できます。
プラットフォーム間で比較する場合は、ビジネス上必要で、意味が比較可能なフィールドだけをマッピングしてください。いいね数、ブックマーク数、商品評価、コメント数はそれぞれ別の指標です。すべてscoreに名前を変えても、共通の尺度になるわけではありません。意味を解釈できていないフィールドについては、単位や意味を推測せず、欠損状態を保持するか辞書を確認してください。
課金は結果の件数から逆算できません。複数ターゲットの機能はターゲットごとに課金されるため、HTTPリクエストは課金単位ではありません。サンプル数の上限が小さくても、返された件数に応じて割引されるわけではありません。現在の同期処理の実装には、空の結果や部分的な取得に対する返金の分岐がありますが、監査のためにクライアント側で実際のbillingと台帳の記録を永続化する必要があります。200や空の配列だけを根拠に精算済みと判断しないでください。
リクエストをログに記録する際は、OWASPのインタラクションIDの設計を参考にしてください。1つのビジネス上の意図に属するイベントを関連付けつつ、アクセストークンなどの機密項目は除外します。デバッグに役立つ情報を残すことは、リクエストヘッダーや生のテキストをそのままログに出力することとは違います。
2つ目のプラットフォームに拡張する際に再利用すべきコード
認証情報の付与、タイムアウト設定、エラーログ、タスク照会のスケジューラー、セキュリティログは再利用できます。一方、パラメータ名とその意味、結果オブジェクトのパス、フィールドマッピング、ページネーションのルール、完了条件は、機能ごとに個別に保つ必要があります。この2つを分けておけば、今後機能を追加するたびにクライアント一式をコピー&ペーストする事態を防げます。
カタログは取得時点でキャッシュし、新しい機能の統合や更新のリリース前に再確認するのが有効です。キャッシュを無期限に保持するのは避けるべきですが、レコードごとにカタログ全体をダウンロードする必要もありません。更新間隔は業務上の変化への許容度に応じて設定し、unknown_capabilityやパラメータの不一致が発生した場合にのみ、対象を絞って再確認してください。
ページネーションと増分取得には特に注意が必要です。特定のアクションがページネーションパラメータと終了シグナルを明示的に提供している場合にのみ実施し、それらがない状態でクライアント側でカーソルを合成しないでください。cronによるクエリで得られるのは複数回の観測結果であり、そのまま完全な履歴や新規コンテンツのすべてになるわけではありません。初版のレポートでは、証明できない全件カバーを主張するのではなく、確認した対象と期間を明記してください。
この方法をそのまま適用するのに向かないタスク
ユーザーに代わって投稿する、販売者プロフィールを管理する、アカウント認可を扱う、プラットフォーム上のデータを変更するといった用途では、公開データのエンドポイントをアカウント管理インターフェースとして扱うのではなく、プラットフォームの公式APIと認可フローを確認してください。非公開コンテンツ、制限付きデータ、許可されていない用途については、統合エンドポイントを使ってもアクセス権限が広がることはありません。
データが公開されている場合でも、保存、分析、再表示は、各プラットフォームの規約と業務目的に照らして判断する必要があります。調査範囲は必要な対象とフィールドに限定し、保持期間を管理してください。投稿者のプロフィール、アクセスパラメータ付きのリンク、原文をそのまま公開ログに出力しないでください。技術的にリクエストできるかどうかと、業務上利用してよいかどうかは、別々に確認すべき事項です。
説明できる結果1件からの開始
初回の統合が終わったら、次の4つを自問してください。呼び出している機能が具体的に何かを明確に説明できるか。すべてのデータ項目を出所までたどれるか。成功、処理中、部分的な返却、結果不明を区別できるか。リクエストが失敗または重複した場合、その結果生じたレコードと課金を説明できるか。
4つの質問すべてに答えられるようになったら、対応するプラットフォームを増やし、同時実行数を増やし、モデルによる分析を組み込みましょう。統合データAPIの価値は、あらゆる違いをなくすことではなく、プラットフォーム間に本当に違いがある箇所だけに独自ロジックを書けばよいようにすることです。下記のドキュメントから機能を選び、少量のサンプルで確認し、結果を正しく保存してから、次のステップに進んでください。
参考資料 LF-01