Contents
概要と目的
この文書は開発チームとプロダクト担当が短期POCから運用移行まで必要な技術情報を迅速に把握できるようにまとめた。Togetter APIの想定エンドポイント、認証フロー、代表的なレスポンススキーマ、運用リスクと回避策を実務目線で提示する。仕様の確定は必ず公式ドキュメントと契約条件で行う前提とする。
API概要と認証
ここではAPIの提供形態と認証方式の想定を示す。実装向けにはOAuth2ベースのBearerトークンを想定し、スコープ管理とトークン更新ロジックが必要になる。以下の仕様例は実装者が即利用できる設計例であり、最終的なフィールド名やパスは公式仕様に合わせること。
エンドポイントの概観
主要エンドポイントの一覧と目的を短く示す。
- ベース(例): https://api.togetter.com
- POST /oauth2/token — アプリ/ユーザ向けのアクセストークン取得
- GET /v1/collections/{collection_id} — まとめ(コレクション)取得
- GET /v1/search — クエリによるまとめ/エントリ検索
- GET /v1/users/{user_id} — 公開プロフィール・作成まとめ一覧
- GET /v1/tweets/hydrate?ids=... — ID群からツイートのハイドレート(想定)
- 各エンドポイントは cursor / page / per_page 等のページネーションを返す想定
認証(OAuth2)
OAuth2の主要なフローと実装上の注意点を整理する。
- サポート想定: client_credentials(アプリ単位)、authorization_code(ユーザ権限)
- ヘッダ: Authorization: Bearer
- トークン更新: expires_in を使って自動更新・リフレッシュを実装
- スコープ管理: 必要最小限のスコープを申請して最小権限で運用
共通レスポンスとヘッダ
レスポンスの共通的な取り扱いと想定ヘッダを示す。
- Content-Type: application/json; charset=utf-8
- レート関連ヘッダ(想定): X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After
- エラーは標準的に HTTP ステータスと JSON body の組合せで返す想定
要点サマリ
ここでの重要点を短くまとめる。
- OAuth2でのアクセストークン管理が必須になる。
- レートヘッダを読む実装を用意することが運用上重要。
- ここに示したパス・フィールドは概念仕様のため公式確認が必要。
実装ガイド: 主要エンドポイントとレスポンススキーマ
実装担当がすぐに参照できるように、主要エンドポイントの具体的なリクエスト/レスポンス仕様例を提示する。以下は概念実装であり、最終仕様は公式ドキュメントに合わせる必要がある。
トークン取得: POST /oauth2/token
トークン取得のリクエストと想定レスポンスを示す。
リクエスト例(client_credentials、Basic認証またはフォーム):
|
1 2 3 4 5 6 |
POST https://api.togetter.com/oauth2/token Content-Type: application/x-www-form-urlencoded Authorization: Basic base64(client_id:client_secret) grant_type=client_credentials&scope=read:collections |
成功レスポンス (200):
|
1 2 3 4 5 6 7 |
{ "access_token": "eyJhbGci...", "token_type": "bearer", "expires_in": 3600, "scope": "read:collections" } |
主なエラー例:
- 400 Bad Request — パラメータ不足や不正
- 401 Unauthorized — client_id/client_secret が誤り
- 429 Too Many Requests — トークン取得レート制限
コレクション取得: GET /v1/collections/{collection_id}
コレクションの完全レスポンススキーマ例を示す。アプリは collection_id を永続化して差分取得に使う。
Intro: コレクション取得はまとめ本体とその項目(items)を返す。必要に応じて items の展開を制御できる設計が望ましい。
リクエスト例:
|
1 2 3 |
GET https://api.togetter.com/v1/collections/col_12345?fields=id,title,description,author,items,created_at&per_page=20 Authorization: Bearer <access_token> |
成功レスポンス (200) の主なスキーマ例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
{ "id": "col_12345", "title": "イベントまとめ", "description": "イベントのまとめ説明", "author": { "id": "u_567", "username": "user", "display_name": "User Name" }, "tags": ["イベント","速報"], "created_at": "2025-11-01T12:34:56Z", "updated_at": "2025-11-02T10:00:00Z", "items": [ { "tweet_id": "1700000000000000000", "text_snapshot": "取得時のツイート本文", "author": { "id": "123", "screen_name": "user" }, "tweet_created_at": "2025-10-31T11:22:33Z", "source_url": "https://twitter.com/.../status/1700000000000000000", "media": [ { "type": "photo", "url": "https://..." } ] } ], "meta": { "total_items": 12, "next_cursor": "eyJ..." } } |
想定されるHTTPステータス:
- 200 OK — 成功
- 401 Unauthorized — トークン無効
- 403 Forbidden — スコープ不足やアクセス制御
- 404 Not Found — collection_id が存在しない
- 429 Too Many Requests — レート制限
エラーレスポンス例 (429):
|
1 2 3 4 5 6 7 8 |
{ "error": { "type": "rate_limit", "message": "Rate limit exceeded", "retry_after": 60 } } |
検索: GET /v1/search
検索エンドポイントの想定仕様。query パラメータに加え cursor ベースのページングをサポートする想定。
リクエスト例:
|
1 2 3 |
GET https://api.togetter.com/v1/search?query=%23event&per_page=20&cursor=eyJ... Authorization: Bearer <access_token> |
レスポンス例(200):
|
1 2 3 4 5 6 7 |
{ "results": [ { "collection": { "id":"col_1", "title":"..." }, "score": 0.95 } ], "next_cursor": "eyJ..." } |
ユーザープロフィール: GET /v1/users/{user_id}
ユーザー情報と作成したまとめの一覧を取得する想定。APIスコープで公開範囲が制限される。
レスポンス例(200):
|
1 2 3 4 5 6 7 8 |
{ "id": "u_567", "username": "user", "display_name": "User Name", "profile_url": "https://togetter.com/user/567", "collections_count": 42 } |
ページネーションと差分取得
差分は since_id / since_timestamp / cursor のいずれかで実装する。大規模取得では cursor ベースが安定する一方、ツイート単位の差分は since_id が使いやすい。
- cursor: 永続的なカーソル文字列で柔軟なページング
- since_id: 最新ID以降を取得する差分取得に適する
- フルリコンシリエーションは定期実行で欠損を検出
要点サマリ
- 各エンドポイントは必須パラメータと想定レスポンスを明確に定義する。
- エラーはHTTPステータスとJSONエラーオブジェクトで扱い、429はRetry-Afterで制御する。
- 本稿のスキーマは概念例であり、実装前に公式仕様を確認する。
レート制限と障害対策
レート制限とエラー発生時の安全な再試行設計が運用品質を左右する。ここでは具体的な再試行ロジック、サーキットブレーカー設計、監視指標を示す。
代表的なエラーと対応方針
以下に主要なHTTPステータスと想定対応を示す。エラー本文は JSON で code / message / details を含める想定。
| HTTP | 想定 code | 原因 | 対応 |
|---|---|---|---|
| 200 | - | 成功 | 正常処理 |
| 400 | invalid_request | パラメータ不備 | リクエスト検証を改善 |
| 401 | unauthorized | トークン無効 | トークン更新・権限確認 |
| 403 | forbidden | スコープ不足 | スコープ申請 or ロール確認 |
| 404 | not_found | リソース無し | IDの存在確認 |
| 422 | validation_error | 検証エラー | 入力バリデーション |
| 429 | rate_limit | レート超過 | Retry-After / バックオフ |
| 5xx | server_error | サーバ障害 | 再試行・フォールバック |
指数バックオフとジッター(実装例)
Retry-After ヘッダがあれば優先的に従う。無ければ指数バックオフ+ジッターを使う。以下は Node.js(axios)での再試行ロジック例(概念):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 概念例: axios を用いた再試行の骨組み async function requestWithRetry(fn, maxAttempts = 6) { for (let attempt = 0; attempt < maxAttempts; attempt++) { try { return await fn(); } catch (err) { const status = err.response?.status; if (status === 401 || status === 403) throw err; // 再試行不可 if (status === 429) { const retryAfter = parseInt(err.response.headers['retry-after'] || '0', 10); if (retryAfter > 0) { await sleep(retryAfter * 1000); continue; } } if (status && status >= 500) { const backoff = Math.min(1000 * Math.pow(2, attempt), 30000); const jitter = Math.random() * 500; await sleep(backoff + jitter); continue; } throw err; } } throw new Error('retry exhausted'); } |
期待動作の注釈: 401/403は認証・権限であり再試行しても無意味な場合が多い。
サーキットブレーカー設計例
サーキットブレーカーは連続エラー時の被害を抑える。設定例:
- オープン条件: 60秒間にエラー率が 50% を超える、または連続5回の 5xx/429
- オープン期間: 60 秒(その後ハーフオープンで1リクエスト試験)
- コールバック: オープン中はキャッシュされたデータや 503 フォールバックを利用
実装は既存ライブラリ(opossum、resilience4j 等)を検討する。
監視とアラート
監視項目は定量的に設定する。
- 成功率(%)、エラー率(5xx/4xx別)
- 平均応答時間 / P95 / P99
- レートリミット残量(X-RateLimit-Remaining)
- キュー滞留数、バックプレッシャー指標
アラート例: レート残量が閾値(例: 10%)を下回ったら通知、P95が通常値の2倍になったら通知。
要点サマリ
- Retry-After を最優先にし、無ければ指数バックオフ+ジッターを使う。
- 401/403 は即時介入が必要で、再試行での回復は期待しない。
- サーキットブレーカーで過負荷時の被害を低減する。
POC 最小実装サンプルと計測手順
短期POCで優先すべきは「認証取得」「データ取得」「差分検証」「コスト算定」の4点である。ここでは最小実装例と計測手順を提示する。
最小実装(Node.js + axios、概念例)
以下は環境変数を用いる例。秘密情報は環境変数やVault等で管理する設計を前提とする。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// 簡易サンプル(概念) const axios = require('axios'); const BASE = process.env.TOGETTER_API_BASE || 'https://api.togetter.com'; const CLIENT_ID = process.env.TOGETTER_CLIENT_ID; const CLIENT_SECRET = process.env.TOGETTER_CLIENT_SECRET; async function getToken() { const res = await axios.post( `${BASE}/oauth2/token`, 'grant_type=client_credentials', { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic ' + Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64') } } ); return res.data.access_token; } async function getCollection(token, id) { const res = await axios.get(`${BASE}/v1/collections/${id}`, { headers: { Authorization: `Bearer ${token}` }, params: { per_page: 20 } }); return res.data; } // 実行フローの例 (async () => { const token = await getToken(); const col = await getCollection(token, 'col_12345'); console.log(col.title, col.meta?.total_items); })(); |
注釈: 上例は概念コードでありエラーハンドリングや再試行、ログのサニタイズを省略している。アクセストークン等はログに出力しない。
期待されるHTTPステータス(POC観点)
- 200: 正常取得。レスポンスボディを検証して期待フィールドがあるか確認する。
- 401/403: 認証・スコープの問題。トークン取得フローと申請スコープを確認する。
- 429: レート超過。Retry-After を見るかバックオフを適用して再試行する。
- 5xx: サーバ側障害。再試行の上で運用含め判断する。
計測項目と手順(優先順)
- 認証成功率とトークン取得レイテンシを測定する。
- 単一リクエストの平均レイテンシとP95を取得する(per-endpoint)。
- 小規模負荷(例: 1RPS, 10RPS)の成功率と429発生閾値を確認する。
- ペイロードサイズを測定してストレージと転送コストを見積もる。
- 差分取得の効率(取得件数あたりのAPIコール数)を評価する。
- コスト試算(APIコール数×単価 + ストレージ)を作成する。
要点サマリ
- POC は小さなRPSで実施し、429や5xxの発生閾値を把握する。
- 計測は認証・取得・差分・コストの4点を優先する。
- サンプルコードでシークレットを直接書かない運用を前提にする。
セキュリティ運用とシークレット管理
APIキーやクライアントシークレットの取り扱いは法務・セキュリティ観点で最重要である。ここでは運用パターンとCIでの注意点を示す。
シークレット管理の実務
シークレット保管の一般的な選択肢と運用の向き不向きを列挙する。
- 環境変数: ローカル開発やコンテナでの簡易管理に有効
- 秘密管理サービス: HashiCorp Vault、AWS Secrets Manager、GCP Secret Manager、Azure Key Vault を推奨
- アクセス制御: 最小権限でIAMロールを付与し、監査ログを有効にする
- 禁止事項: ソース管理(git)への書き込みや公開リポジトリへの配置は避ける
CI/CDでの扱い
CIのシークレット運用で押さえる点を示す。
- 秘密はCIの「シークレット」機能に登録し、ログに出力しない
- PRやForkからの実行でシークレットが使えない設定にする
- アクセスは最小権限にし、有効期限やローテーションの仕組みを設ける
ログと監査
ログには個人情報やアクセストークンを残さない。エラーログの出力はサニタイズして保存し、誰がいつどの操作をしたかが追える監査ログを用意する。
データ品質・プライバシー・著作権
データ利用に伴う法的リスクや品質担保の実務ルールを整理する。法務との協働が前提である。
削除要求と権利行使対応
削除や非公開への対応フローを自動化する設計が望ましい。
- API上で取得できなくなったコンテンツは社内DB上も削除/マスクするフローを用意する
- ユーザーからの削除要求はトレース可能なワークフローで処理する
- 削除処理はログとエビデンスを残す
保存方針とアーカイブ
保存するデータ粒度により影響が異なる設計指針。
- IDのみ保存して都度ハイドレートする: ストレージ抑制だがAPI依存が強まる
- テキストスナップショットを保存: APIコールを減らせるが保存コストと権利管理が増える
- 退避データの暗号化、アクセス制御、保持期間の明確化が必要
表示要件と著作権
ツイートの再利用には出典表示や埋め込み要件がある場合が多い。表示要件や全文転載の可否は利用規約で確認し、法務判断を得る。
ケーススタディ: Twilog連携(概念例)
Twilog連携は代表的なケースだが、公開情報が変動するためここでは概念的な選択肢と運用教訓を示す。導入判断時は原文のプレスリリースや企業告知を確認することを推奨する。
選択肢比較(概念例)
- Enterprise契約で網羅性を確保する: 安定だがコスト高
- カバレッジを限定してコストを抑える: 重要ユーザーやイベントに絞る
- ハイブリッド: ID保存+オンデマンドハイドレートでバランスを取る
- データプロバイダへ委託: 開発負担を削減するがロックイン・コストを検討
運用上の教訓(概念)
- 課金単位を意識した機能設計が重要
- 差分取得+多層キャッシュでAPIコールを最小化する
- 削除要求の自動対応ルールを早期に整備しておく
参考リンクと一次資料(確認事項)
導入判断時は下記のような一次資料を直接確認することを推奨する。掲載されている情報は公開時点の告知や報道を参照しており、詳細や掲載日・範囲は各リンク先の本文で確認すること。
- Togetter の公式告知ページ(例): https://togetter.com/li/2144841
- 企業向けリリースやプレス(例): https://www.atpress.ne.jp/news/355297
- OAuth2 一般仕様(RFC 6749): https://datatracker.ietf.org/doc/html/rfc6749
注: 上記リンクは参考例であり、具体的な契約条件やAPI仕様は公式ドキュメントや担当窓口で確認すること。
まとめと次のステップ
Togetter APIの導入では、認証・レート制御・データ保存方針・法務確認が主要な検討ポイントである。まずは小さなスコープでPOCを回し、認証フロー、レスポンスの主要フィールド、差分取得の効率、レート閾値を測定する。POC結果を基にスケール方針とコスト・契約の要件を定義し、運用設計(シークレット管理・削除対応・監視)を固めることが次のフェーズとなる。