2人チームのエージェンシーが X の従量課金リード料を払わずに4つのクライアントアカウントの DM・メンションを監視している方法 — UnifyPort
2026年1月、リスボンの2人体制のソーシャルメディアエージェンシーが、4つのクライアントの X(Twitter)アカウントを管理していました。EC ブランド2社、SaaS スタートアップ1社、ローカルのレストランチェーン1社です。業務内容はシンプルで、各アカウントの DM とメンションを監視し、数時間以内に返信、クライアント本人の対応が必要なものはエスカレーションする、というもの。技術的にも単純で、Node.js のサービスが各アカウントの X API を30秒ごとにポーリングし、新着メッセージを共有 Slack チャンネルにルーティングしていました。
X の旧料金体系——2023年から続いていた固定月額プラン——では、この構成は Basic ティアで月額 $100。予測可能で予算に組み込みやすく、クライアントが払うリテイナーで余裕をもってカバーできるレベルでした。
そして2月が来ました。
課金メーターが動き出す
2026年2月3日、X は固定ティア料金を従量課金に切り替えました。リード・ライト問わず、すべての API コールにリクエスト単価が付くようになりました。月額の上限はなくなり、「ティア内は呼び放題」前提で設計されたポーリングアーキテクチャが、突然メーターを回し続けることに。
計算は即座でした。4つのクライアントアカウント、それぞれ30秒ごとに DM とメンションをポーリング。毎分8リード(アカウントあたり2エンドポイント × 4アカウント)、1日11,520回、月間約345,600回——これは監視だけのコストで、1通のメッセージも受信していない状態での数字です。
4月20日の料金改定で、自己所有リソースのリードは1回 $0.001 に引き下げられました。月間の監視リードコストは約 $346 に。しかし同じ改定でライトリクエスト(返信)は $0.010 から $0.015 に値上げされました。エージェンシーの月間返信数は4アカウント合計で400〜600通。$0.015 換算で $6〜$9 の増加です。単体では大きくありませんが、方向性が気になりました。クライアントアカウントが1つ増えるたびにポーリングループが増え、返信が増えるたびに両側から請求が膨らむ構造です。
本当に高いのはレートではなく、アーキテクチャ
創業者が仮に Q3 でクライアントを2社追加した場合の試算をしてみました(パイプライン上、十分現実的なシナリオ)。ポーリングリードだけで概ね倍増します。1回あたりのレートは確かに低いのですが、呼び出し量は構造的なもの——メッセージが実際に何通届いたかではなく、サービスが新着メッセージをチェックする頻度で決まります。DM がゼロの日曜日でも、ポーリングループは同じ速度で動き、コストは製品ローンチ当日とまったく同じです。
X の従量課金モデルで、料金比較記事には出てこない部分がこれです。メッセージを待つコストはゼロではない。そしてそれは実際のメッセージ量ではなく、監視アーキテクチャに比例してスケールします。4アカウントを30秒ごとにポーリングすれば、受信メッセージが10通でも10,000通でも月間345,600リードです。
ポーリング間隔を伸ばすのが最も直感的な対策でした。チームは1週間、2分間隔を試しました。レスポンスタイムが明らかに悪化し、DM が最悪4分近く未読になるケースが発生。2社のクライアントとは「2時間以内の応答」SLA を契約していました。SLA 違反にはなりませんでしたが、サービスの質感が「ほぼリアルタイム」から「そのうち」に変わってしまいました。3日後に元に戻しました。
プルからプッシュへ
正しい解決策はポーリングの最適化ではなく、ポーリングの廃止でした。チームは4つのクライアントの X アカウントをすべて UnifyPort に接続し、DM とメンションをリアルタイムで webhook にプッシュする方式に切り替えました。ポーリングループなし、従量リード課金なし、チェック頻度に比例するコストなし。
アーキテクチャの変化は以下のとおりです:
Before(ポーリング):
サービス ──► X API(DM読取) ×4アカウント ×2回/分 = 345,600 リード/月
サービス ──► X API(メンション読取) ×4アカウント ×2回/分 = 345,600 リード/月
合計:~691,200 課金 API リード/月
After(webhook プッシュ):
X アカウント ──► UnifyPort ──► POST /webhook ──► Slack(クライアント A)
X アカウント ──► UnifyPort ──► POST /webhook ──► Slack(クライアント B)
X アカウント ──► UnifyPort ──► POST /webhook ──► Slack(クライアント C)
X アカウント ──► UnifyPort ──► POST /webhook ──► Slack(クライアント D)
合計:0 X API リード
各アカウントのインバウンドメッセージは message.received イベントとして配信されます。同じチームが今後 WhatsApp や Telegram、あるいは日本市場では LINE のアカウントを同じクライアント向けに追加した場合も、まったく同じフォーマットで届きます:
{
"event": "message.received",
"account_id": "acct_client_a",
"provider": "twitter",
"from": "user_7d2e1f",
"text": "Hey, is the summer sale still on? Saw a post but the link was broken",
"timestamp": 1750320000,
"message_id": "x_msg_8a3b2c"
}
webhook ハンドラーは HMAC-SHA256 で各配信の署名を検証し、account_id に基づいて対応するクライアントの Slack チャンネルにルーティングします:
app.post("/webhook", (req, res) => {
if (!verifySignature(req)) return res.sendStatus(401);
const evt = req.body;
if (evt.event === "message.received") {
const channel = clientChannelMap[evt.account_id];
slack.postMessage(channel, {
text: `[${evt.provider}] ${evt.from}: ${evt.text}`,
metadata: { messageId: evt.message_id },
});
}
res.sendStatus(200);
});
4アカウント、1エンドポイント、1つの署名キー。ポーリングサービスは完全に停止しました。
何が変わったか
チームの X 関連 API コストは月額約 $350(クライアント追加で増加傾向)からリード課金ゼロに。レスポンスレイテンシーはむしろ改善しました——イベントはメッセージ送信後数秒以内に届き、次のポーリングサイクルを待つ必要がありません。新しいクライアントアカウントの追加も、請求書にポーリングループを1つ追加する作業ではなく、clientChannelMap に1行追加する作業になりました。
2人チームの X DM・メンション返信方法は変わっていません——Slack から、UnifyPort の返信エンドポイント経由でルーティングします。変わったのは、「4つの X アカウントの監視」がモデリングやクライアントへの説明、スケーラビリティの心配が必要な API コストではなくなったこと。Q3 のパイプラインでアカウントが2つ増えても、webhook が4つではなく6つ受け取るだけ。請求書には差が出ません。
複数の X アカウントを管理するエージェンシーやチーム——特に X API コストがメッセージ量ではなくポーリング頻度に比例してスケールするチーム——にとって、アーキテクチャの問いは「最も安いポーリング間隔は何か」ではありません。プッシュ型 webhook がメーターを回さずに同じメッセージを配信できるのなら、プルモデル自体が必要かどうか、という問いです。