twilio-admin について
twilio-adminは、本番環境のTwilioを管理するエンジニア向けのスキルです。CLIとAPIを使い、サブアカウント、使用量とコスト、電話番号、コンプライアンスをガードレール付きで監査可能な形で運用します。
主な機能
- 01ガードレール付きのサブアカウント管理
- 02使用量の監視と異常検知
- 03電話番号インベントリの管理
- 04コンプライアンス要件の追跡
- 05管理操作の記録
活用シーン
- 01インシデント対応時のアカウント停止
- 02サブアカウント間の異常な使用量の検出
- 03番号のMessaging Servicesへの割り当て
- 04A2Pとトールフリー認証状況の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ alphaonedev/ openclaw-graph --skill twilio-adminインストール後、Claude Code で/twilio-adminを入力して読み込まれたか確認します。
詳細
twilio-admin
目的
本番環境の Twilio アカウントを、信頼性と監査可能性を確保しながら管理します。
- サブアカウントを安全に作成、設定、一時停止、閉鎖します(ガードレールとロールバックを備えています)。
- 親アカウントとサブアカウント全体の使用状況とコストを監視し、異常を検知して予算を適用します。
- 電話番号を大規模に管理します(購入、解放、ポートイン、Messaging Services/Voice アプリへの割り当て)。
- コンプライアンス体制を維持します。SHAKEN/STIR、A2P 10DLC、フリーダイヤル認証、TrustHub バンドル、監査ログが対象です。
- CI/CD やオンコールの運用手順に適した、再現可能な運用ワークフロー(CLI と API)を提供します。
このスキルは、本番トラフィックに影響を与えることなく、Twilio の管理機能を決定論的かつスクリプトで制御する必要があるエンジニアを対象としています。
前提条件
Twilio アカウントと権限
- 以下の権限を持つ Twilio 親アカウント:
- サブアカウントの作成/管理
- 使用状況レコードの閲覧
- 電話番号の管理
- TrustHub/A2P/フリーダイヤル認証へのアクセス(該当する場合)
- 以下が必要です。
ACCOUNT_SID(AC...で始まるもの)AUTH_TOKEN
- サブアカウントを操作する場合は、各サブアカウントの SID(
AC...)と、サブアカウントごとの認証情報を使用する場合は、その認証トークン(任意)が必要です。
サポート対象のツールバージョン(固定)
- twilio-cli:
5.6.0 - Node.js(twilio-cli のランタイム):
20.11.1(LTS) - Python(管理スクリプト用):
3.11.8 - twilio-python:
9.4.1 - jq:
1.7 - curl:
8.5.0 - OpenSSL:
3.0.13(TLS 検査/証明書ツール用) - Docker(分離された実行環境で使用する場合は任意):
25.0.3
OS サポート
- Ubuntu
22.04/24.04 - Fedora
39/40 - Intel および Apple Silicon 搭載の macOS
14(Sonoma)
認証の設定(推奨パターン)
- ローカル開発:Twilio CLI プロファイルと環境変数を使用します。
- CI:Vault(AWS Secrets Manager/GCP Secret Manager/Vault)から短期間有効なシークレットを取得し、環境変数として注入します。
- 本番環境の自動化:該当する場合は Twilio API キーを分け、厳密にスコープを設定します。CI ではプライマリ Auth Token の使用を避けてください。
注:Twilio の従来のモデルでは、Account SID と Auth Token を使用します。一部の製品は API キーに対応していますが、管理操作では依然として Account SID と Auth Token が必要となることがよくあります。Auth Token はルートシークレットとして扱ってください。
主要な概念
親アカウントとサブアカウント
- 親アカウント:請求の所有者であり、サブアカウントを作成/管理でき、統合レポートを利用できます。
- サブアカウント:リソース(電話番号、Messaging Services、アプリ)と使用状況が分離されており、個別に一時停止/閉鎖できます。
運用モデル:
- サブアカウントを使用して、環境(本番/ステージング)、テナント、または事業部門を分離します。
- 可能な場合は、請求とコンプライアンスを親アカウントに一元化します。
アカウントのライフサイクル状態
Twilio アカウントには status フィールドがあります。
active:通常稼働suspended:トラフィックはブロックされますが、リソースは保持されますclosed:アカウントは閉鎖され、リソースが解放される可能性があります。実質的に取り消しできません
使用状況レコードと請求
- Usage Records API:使用状況イベント(分数、メッセージなど)をカテゴリ別にほぼリアルタイムで提供します。
- 請求書:月次の請求資料です。アラートには必ずしも適していません。
- 異常検知には、日次/時間単位の粒度で Usage Records を使用することを推奨します。
電話番号のインベントリ
Twilio の電話番号は、以下の情報を持つリソースです。
- E.164 電話番号
- 機能:
sms、mms、voice、fax - 設定:Voice URL、Messaging webhook、ステータスコールバック、緊急連絡先住所(米国)など
大規模な運用では:
- コストとスループットを最適化するため、Messaging Services を番号プールおよび地理的マッチングと組み合わせて使用します。
- アプリケーションロジックを単一の電話番号に直接ひも付けないでください。
コンプライアンス関連機能(概要)
- A2P 10DLC(米国):ブランドとキャンペーンの登録です。米国での A2P SMS の多くのユースケースで必須です。
- フリーダイヤル認証(米国/カナダ):到達率とスループットを高めるために必要です。
- SHAKEN/STIR(Voice):発信者 ID の認証であり、通話の接続状況やラベル表示に影響します。
- TrustHub:顧客プロファイル、エンドユーザープロファイル、補足書類、バンドルを扱います。
Webhook と監査可能性
- メッセージング/音声のステータスコールバックは、配信状況の確認とデバッグに不可欠です。
- Twilio Console では監査イベントを確認できます。プログラムからのアクセス可否は製品によって異なります。API が限られている場合は、自動化処理で独自の監査証跡(誰が/何を/いつ)を記録してください。
インストールとセットアップ
公式 Python SDK — 管理/アカウント管理
リポジトリ: https://github.com/twilio/twilio-python
PyPI: pip install twilio · サポート対象: Python 3.7–3.13
from twilio.rest import Client
client = Client()
# List subaccounts
for acct in client.api.v2010.accounts.list():
print(acct.sid, acct.friendly_name, acct.status)
# Create subaccount
sub = client.api.v2010.accounts.create(friendly_name="Staging Account")
sub_client = Client(client.username, client.password, sub.sid)
# Rotate auth token (master account key management)
keys = client.api.v2010.accounts(client.account_sid).keys.list()
for k in keys:
print(k.sid, k.friendly_name, k.date_created)
出典:twilio/twilio-python — accounts
Ubuntu 22.04/24.04
sudo apt-get update
sudo apt-get install -y curl jq python3.11 python3.11-venv python3-pip ca-certificates gnupg
Node.js 20.11.1(NodeSource)をインストールします。
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
node --version # expect v20.x
npm --version
Twilio CLI 5.6.0 をインストールします。
sudo npm install -g [email protected]
twilio --version
任意:管理ワークフローでよく使用される Twilio CLI プラグインをインストールします。
twilio plugins:install @twilio-labs/[email protected]
twilio plugins:install @twilio-labs/[email protected]
twilio plugins:install @twilio-labs/[email protected]
Python 環境:
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip==24.0
pip install twilio==9.4.1 requests==2.31.0 python-dateutil==2.9.0.post0
Fedora 39/40
sudo dnf install -y curl jq python3.11 python3.11-pip python3.11-virtualenv ca-certificates
sudo dnf install -y nodejs npm
node --version
Twilio CLI をインストールします。
sudo npm install -g [email protected]
twilio --version
Python 仮想環境:
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip==24.0
pip install twilio==9.4.1 requests==2.31.0 python-dateutil==2.9.0.post0
macOS 14(Intel + Apple Silicon)
Homebrew をインストールし(必要な場合)、次に以下を実行します。
brew update
brew install jq [email protected] node@20
Node 20 が有効になっていることを確認します。
brew link --overwrite node@20
node --version
Twilio CLI をインストールします。
npm install -g [email protected]
twilio --version
Python 仮想環境:
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip==24.0
pip install twilio==9.4.1 requests==2.31.0 python-dateutil==2.9.0.post0
Twilio CLI の認証
Twilio CLI はプロファイルを次の場所に保存します。
- macOS/Linux:
~/.twilio-cli/config.json
対話形式でログインします(プロファイルが書き込まれます)。
twilio login
非対話形式(CI)では環境変数を使用します。
export TWILIO_ACCOUNT_SID="ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
export TWILIO_AUTH_TOKEN="your_auth_token"
確認します。
twilio api:core:accounts:fetch --sid "$TWILIO_ACCOUNT_SID"
主な機能
サブアカウントのライフサイクル管理
操作:
- 決定的な命名規則とメタデータを使用してサブアカウントを作成します。
- (対応している場合)認証情報をローテーションし、シークレットを配布します。
- インシデント対応中にサブアカウントを一時停止します。
- リソースをクリーンアップした後、サブアカウントを閉鎖します。
本番環境での重要なガードレール:
- 次のすべてが完了するまで、サブアカウントを閉鎖しないでください。
- すべての電話番号が解放または移行されている
- メッセージングサービスの処理が完了している
- Webhook が無効化されているか、安全な受け口を指している
- Verify サービスと SendGrid インテグレーションが切り離されている(使用している場合)
使用状況の監視と異常検知
- カテゴリ別(SMS、MMS、音声通話時間、Verify など)に、日ごとの使用状況を取得します。
- サブアカウント全体で集計します。
- ベースライン(7 日間の移動平均)と比較し、乖離があればアラートを出します。
- サブアカウントを一時停止するか、メッセージングサービスを無効化して予算を適用します。
大規模な電話番号管理
- 必要な機能を備えた電話番号を検索して購入します。
- 電話番号をメッセージングサービスに割り当てます(プール化)。
- 音声 URL/メッセージング Webhook を設定します。
- 電話番号を安全に解放します(アクティブな依存関係がないことを確認します)。
- 電話番号の在庫と所有権を追跡します(CMDB のタグを使用します。Twilio では電話番号に任意のタグを設定できません)。
コンプライアンス:A2P 10DLC、フリーダイヤル、SHAKEN/STIR、TrustHub
- 米国の A2P トラフィックが、登録済みキャンペーンを経由するようにルーティングされていることを検証します。
- フリーダイヤル番号が本番環境で使用される前に認証済みであることを確認します。
- 発信者 ID の認証状態(SHAKEN/STIR)を確認し、なりすましのパターンを避けます。
- 規制対象地域向けの TrustHub バンドルと関連書類を維持します。
監査ログと変更追跡
- Twilio Console には監査イベントがありますが、API の対応範囲は異なります。
- 本番環境では、自動化レベルの監査ログを実装します。
- 管理操作をすべて記録します(誰が/何を/いつ/なぜ)
- リクエスト/レスポンスのメタデータを保存します(シークレットは秘匿します)
- インシデントチケットと関連付けます
コマンドリファレンス
注:
- Twilio CLI のコマンドグループは、インストール済みのプラグインと CLI のバージョンによって異なります。
- CLI の対応範囲が不十分な場合は、
curlまたはtwilio-pythonを使用して REST API を直接呼び出してください。
Twilio CLI のグローバルフラグ
一般的なフラグ(ほとんどのコマンドに適用されます):
-o, --output [json|tsv|csv|human]:出力形式--properties <props>:フィールドを選択(カンマ区切り)--no-header:ヘッダーを抑制(tsv/csv)--limit <n>:一覧結果の件数を制限--page-size <n>:一覧表示のページサイズ--page-token <token>:ページネーショントークン--profile <name>:~/.twilio-cli/config.jsonの名前付きプロファイルを使用--log-level [debug|info|warn|error]:CLI のログ詳細度
例:
twilio api:core:accounts:list -o json --limit 50
twilio api:core:incoming-phone-numbers:list --properties sid,phoneNumber,friendlyName -o tsv --no-header
アカウント(親アカウント+サブアカウント)
アカウントを一覧表示します:
twilio api:core:accounts:list --limit 200 -o json
アカウントを取得します:
twilio api:core:accounts:fetch --sid ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -o json
サブアカウントを作成します:
twilio api:core:accounts:create \
--friendly-name "prod-tenant-acme" \
-o json
アカウントのステータスを更新します(一時停止/再有効化):
twilio api:core:accounts:update --sid ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --status suspended -o json
twilio api:core:accounts:update --sid ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --status active -o json
アカウントを閉鎖します:
twilio api:core:accounts:update --sid ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --status closed -o json
本番環境でのルール:閉鎖は実質的に元に戻せません。まず
suspendedにし、クリーンアップ後に閉鎖してください。
使用状況レコード
使用状況レコードを一覧表示します(日次):
twilio api:core:usage:records:list \
--category sms \
--start-date 2026-02-01 \
--end-date 2026-02-20 \
--granularity daily \
-o json
フラグ(使用状況レコード一覧):
--category <string>:例:sms、mms、calls、phonenumbers、verifyなど。--start-date YYYY-MM-DD--end-date YYYY-MM-DD--granularity [daily|hourly|all]
カテゴリ名はTwilioによって定義されています。既存の使用状況を確認するか、お使いのアカウント向けのTwilioドキュメントを参照して列挙してください。
着信電話番号
電話番号を一覧表示します:
twilio api:core:incoming-phone-numbers:list --limit 200 -o json
SIDで電話番号を取得します:
twilio api:core:incoming-phone-numbers:fetch --sid PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -o json
電話番号の設定を更新します:
twilio api:core:incoming-phone-numbers:update \
--sid PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
--friendly-name "prod-sms-us-east-01" \
--sms-url "https://api.example.com/twilio/sms/inbound" \
--sms-method POST \
--status-callback "https://api.example.com/twilio/sms/status" \
--status-callback-method POST \
--voice-url "https://api.example.com/twilio/voice/inbound" \
--voice-method POST \
-o json
電話番号を解放します:
twilio api:core:incoming-phone-numbers:remove --sid PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
利用可能な電話番号(検索+購入)
SMSと音声に対応した米国の市内番号を検索します:
twilio api:core:available-phone-numbers:local:list \
--iso-country US \
--in-region CA \
--sms-enabled true \
--voice-enabled true \
--limit 20 \
-o json
電話番号を購入します:
twilio api:core:incoming-phone-numbers:create \
--phone-number "+14155552671" \
--friendly-name "prod-acme-us-ca-01" \
-o json
Messaging Services(プール、地域一致、送信者固定)
Messaging Servicesを一覧表示します(Messaging APIグループが必要です。CLIでの対応状況は異なる場合があります):
CLIが対応している場合:
twilio api:messaging:v1:services:list -o json --limit 200
サービスを作成します:
twilio api:messaging:v1:services:create \
--friendly-name "prod-us-messaging" \
--use-inbound-webhook-on-number true \
--sticky-sender true \
--smart-encoding true \
-o json
サービスに電話番号を追加します(電話番号SID):
twilio api:messaging:v1:services:phone-numbers:create \
--service-sid MGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
--phone-number-sid PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
-o json
地域一致を有効にします(サービス設定で対応している場合。CLIで公開されていないAPIフィールドが必要になる場合があります): 必要に応じて、curl経由でREST APIを使用してください。
TrustHub/A2P/フリーダイヤル(API優先)
CLIの対応状況には一貫性がありません。REST APIをcurlまたはtwilio-pythonとともに使用してください。
基本の認証ヘッダー:
export TWILIO_ACCOUNT_SID="ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
export TWILIO_AUTH_TOKEN="your_auth_token"
basic_auth="$(printf '%s:%s' "$TWILIO_ACCOUNT_SID" "$TWILIO_AUTH_TOKEN" | base64)"
例:TrustHubの顧客プロファイルを一覧表示します(エンドポイントは、地域や製品の提供状況によって異なる場合があります):
curl -sS "https://trusthub.twilio.com/v1/CustomerProfiles" \
-H "Authorization: Basic $basic_auth" | jq .
404が返される場合、お使いのアカウントでTrustHubが有効になっていないか、製品構成によってエンドポイントが異なる可能性があります。Consoleと、お使いのアカウント向けのTwilioドキュメントで確認してください。
監査イベント(ConsoleとAPI)
Twilioの監査イベントAPIの提供状況は異なります。お使いのアカウントで対応している場合は、https://accounts.twilio.com/v1/...などのエンドポイントを利用できることがあります。多くの本番環境では、Twilio Consoleの監査ログを人が確認できる情報源として扱い、独自の自動化監査ログを実装してください。
設定リファレンス
Twilio CLIの設定
パス:
~/.twilio-cli/config.json
例(複数のプロファイル):
{
"profiles": {
"prod-parent": {
"accountSid": "YOUR_ACCOUNT_SID",
"authToken": "prod_parent_auth_token",
"region": "us1",
"edge": "ashburn"
},
"stage-parent": {
"accountSid": "YOUR_ACCOUNT_SID",
"authToken": "stage_parent_auth_token",
"region": "us1"
}
},
"activeProfile": "prod-parent"
}
運用上のガイダンス:
- このファイルをコミットしないでください。
- 共有マシンでは、ファイルシステムの権限を適切に設定してください:
chmod 600 ~/.twilio-cli/config.json
OpenClawスキルの設定(推奨)
パス(リポジトリ内):
./.openclaw/skills/twilio-admin.toml
例:
[twilio]
parent_account_sid = "YOUR_ACCOUNT_SID"
region = "us1"
edge = "ashburn"
[policy]
require_ticket_id = true
allowed_close_environments = ["dev", "sandbox"]
suspend_before_close = true
suspend_grace_period_hours = 24
[usage_alerts]
currency = "USD"
daily_spend_soft_limit = 250.00
daily_spend_hard_limit = 500.00
anomaly_multiplier = 2.5
lookback_days = 7
[number_management]
default_sms_url = "https://api.example.com/twilio/sms/inbound"
default_status_callback = "https://api.example.com/twilio/sms/status"
default_voice_url = "https://api.example.com/twilio/voice/inbound"
環境変数(CIで安全に使用できる契約)
パス(CIシステム):
- GitHub Actionsのシークレット/GitLab CIの変数/Vaultによる注入
必須:
export TWILIO_ACCOUNT_SID="YOUR_ACCOUNT_SID"
export TWILIO_AUTH_TOKEN="prod_parent_auth_token"
任意(監査証跡のため推奨):
export CHANGE_TICKET_ID="INC-20481"
export CHANGE_ACTOR="[email protected]"
export CHANGE_REASON="Suspend tenant due to suspected SMS fraud"
統合パターン
インシデント対応の自動化との組み合わせ
パターン:
- 異常を検知します(使用量の急増、キャリアの障害、Verifyの不正利用)。
- サブアカウントを自動的に一時停止するか、Messaging Serviceを無効にします。
- 状況とロールバック手順を添えて、オンコール担当者に通知します。
パイプラインの例(CIジョブの擬似コード):
python scripts/twilio_usage_anomaly.py --since 2026-02-20 --threshold-multiplier 3.0
python scripts/twilio_suspend_subaccount.py --subaccount AC333... --ticket INC-20481 --reason "SMS spike"
python scripts/post_to_pagerduty.py --incident-key twilio-ac333 --summary "Suspended Twilio subaccount AC333..."
Terraformとの組み合わせ(IaC)
Twilio Terraformプロバイダーの対応範囲は限定的で、時間とともに変化します。安定したリソース(対応している場合)にはTerraformを使用し、以下にはこのスキルを使用してください:
- 緊急対応(停止/閉鎖)
- 電話番号の在庫管理操作
- Terraformでは適切にモデル化されていないコンプライアンスワークフロー
パターン:
- Terraformでベースラインとなるアプリ/Webhook/Messaging Servicesを管理します。
- 管理スクリプトで電話番号とアカウントのライフサイクルを管理します。
データウェアハウスとの組み合わせ(コストと配信到達率の分析)
使用状況レコードを毎日BigQuery/Snowflakeにエクスポートします:
account_sid、category、date、price、usageをキーとするusage_recordsテーブル。
次のデータと結合します:
- メッセージのステータスコールバック(配信済み/失敗)
- キャリアのエラーコード(例:
30003) - オプトアウトイベント(STOP)
Twilio Messaging/Voice/Verify/SendGrid の運用スキルを組み合わせる
- twilio-admin はアカウント/電話番号/コンプライアンスの基本機能を提供します。
- Messaging スキルは以下を処理します:
- ステータス Webhook、STOP の処理、10DLC ルーティング、トールフリー番号の認証チェック
- Voice スキルは以下を処理します:
- TwiML アプリ、SIP トランキング、通話の録音/文字起こし、SHAKEN/STIR の準拠状況の検証
- Verify スキルは以下を処理します:
- Verify V2 サービス、レート制限、Fraud Guard
- SendGrid スキルは以下を処理します:
- テンプレート、IP ウォーミング、バウンス/スパムの抑制
エラー処理とトラブルシューティング
CLI と API レベルのエラーを両方記載します。それぞれについて、症状、根本原因、対処方法を示します。
- 認証の失敗
エラー:
Twilio could not authenticate the request. Please check your credentials. (20003)
根本原因:
TWILIO_AUTH_TOKENが間違っています- サブアカウントの SID に親アカウントのトークンを使用している、またはその逆です
- ローテーションしたトークンが CI で更新されていません
対処方法:
- 環境変数と有効な CLI プロファイルを確認します:
twilio profiles:list twilio api:core:accounts:fetch --sid "$TWILIO_ACCOUNT_SID" - シークレットをボールトでローテーションし、CI を再デプロイします。
- 電話番号の形式が無効
エラー:
The 'To' number +1415555 is not a valid phone number. (21211)
根本原因:
- E.164 形式ではありません
- 国番号がありません
- 本番環境でダイヤルできないテストデータを使用しています
対処方法:
- アプリケーション層で E.164 形式に正規化します。
- 送信前に検証を追加し、E.164 形式でない番号を拒否します。
- レート制限
エラー:
Rate limit exceeded (20429)
根本原因:
- バックオフなしで一括管理操作を実行しています
- 多数のサブアカウントに対してスクリプトを並列実行しています
対処方法:
- ジッターを加えた指数バックオフを実装します。
- 同時実行数を減らし、操作をバッチ処理します。
- CLI のループでは、スリープを追加します:
for sid in $(cat subaccounts.txt); do twilio api:core:accounts:fetch --sid "$sid" -o json sleep 0.3 done
- キャリアによる配信失敗
エラー(メッセージステータスコールバック/ログ):
Message Delivery - Error Code 30003: Unreachable destination handset
根本原因:
- 加入者に接続できない、またはオフラインです
- キャリアによるフィルタリングです
- 無効な番号や番号ポータビリティに関する特殊なケースです
対処方法:
- 試行回数を制限し、それ以降は再試行不可として扱います。
- キャリアごとの失敗率を追跡し、別のルート(Messaging Service、認証済みの送信者タイプ)の利用を検討します。
- フィルタリングを減らすため、コンプライアンス要件(10DLC/フリーダイヤル番号の認証)を満たしていることを確認します。
- アカウントコンテキストの誤りによる権限エラー/リソース未検出
エラー:
The requested resource /IncomingPhoneNumbers/PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX was not found (20404)
根本原因:
- 番号が、使用中の認証情報とは別のサブアカウントに属しています
- 親アカウントの認証情報を使用しているのに、サブアカウントに関連付けられたリソースを誤って照会しています(またはその逆です)
対処方法:
- 各サブアカウントの番号一覧を確認して所有アカウントを特定するか、インベントリの対応表を維持します。
- そのアカウントに対応する正しい認証情報/プロファイルを使用します。
- アクティブなリソースがある状態でアカウントを閉鎖しようとしている
症状:
- アカウントは閉鎖されますが、番号は解放されるまで課金が続くか、内部ワークフローで閉鎖に失敗します。
根本原因:
- アカウントを閉鎖しても、すべてのリソースがすぐに自動解放されるわけではありません。
- 番号は、明示的に解放されるまで「所有中」の状態のままになる場合があります。
対処方法:
- 閉鎖前のチェックリスト:
- 着信用電話番号を一覧表示して削除します
- メッセージングサービスとの関連付けを解除します
- Webhook を無効にします
- 閉鎖前のクリーンアップを自動化します。
- 2xx 以外のレスポンスによる Webhook の再試行集中
症状:
- Webhook の配信が繰り返され、負荷が増加し、イベントが重複します。
根本原因:
- Webhook エンドポイントが 500 エラーを返す、またはタイムアウトしています。
- 下流の依存先が遅いです。
対処方法:
- Webhook エンドポイントがすぐに 2xx を返すようにし、処理を非同期キューに入れます。
- 冪等性キーとして
MessageSid/CallSidを使用します。 - サーキットブレーカーを追加し、負荷を抑制します。
- Webhook エンドポイントの TLS/証明書の問題
症状(Twilio デバッガー/ログ):
- TLS ハンドシェイクの失敗を示す Webhook エラーが発生します。
根本原因:
- 証明書の有効期限が切れています
- 証明書チェーンが不完全です
- 暗号スイートに対応していません
対処方法:
- 次のコマンドで検証します:
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts - 証明書を更新し、チェーン全体が揃っていることを確認して、最新の TLS 設定を使用します。
- メッセージングのコンプライアンス要件(10DLC/フリーダイヤル番号)
症状:
- スループットが急に低下する、フィルタリングが増える、またはポリシー関連のエラーでメッセージが失敗します。
根本原因:
- 米国向けトラフィックの A2P キャンペーンが未登録です
- フリーダイヤル番号が認証されていません
- 用途とコンテンツが一致していません
対処方法:
- Console/TrustHub で登録状況を確認します。
- 米国向け A2P トラフィックは、登録済みキャンペーンの番号/サービス経由でルーティングします。
- テンプレートとオプトインのフローを更新します。
- 音声発信者 ID の認証に関する問題(SHAKEN/STIR)
症状:
- 通話に「スパムの可能性あり」というラベルが付く、または応答率が低下します。
根本原因:
- 未認証の発信者 ID を使用しています
- 発信元の識別情報が一致していません
- 設定が原因で認証レベルが低くなっています
対処方法:
- 所有する Twilio 番号を発信者 ID として使用します。
- なりすましを避け、発信元に一貫性を持たせます。
- SHAKEN/STIR のガイダンスと通話フローを確認します。
セキュリティ強化
シークレット管理
TWILIO_AUTH_TOKENはシークレットマネージャーにのみ保存してください。- 認証トークンは決してログに記録せず、構造化ログではマスキングしてください。
- インシデント発生時またはスタッフの退職時には、Auth Token をローテーションしてください。
ローカルファイルシステム:
~/.twilio-cli/config.jsonの権限は0600にしてください。- macOS では、可能な場合、自動化には Keychain を利用したシークレットストレージを優先してください。
ネットワーク制御
- Webhook エンドポイント:
- HTTPS のみを強制してください
- インバウンド Webhook では Twilio の署名(X-Twilio-Signature)を検証してください
- エンドポイントにレート制限を適用し、WAF で保護してください
- ロードバランサーで TLS を終端する場合は、エンドツーエンドの完全性と正しいホストヘッダーを確保してください。
変更管理
- 破壊的な操作(番号の一時停止/閉鎖/解放)には
CHANGE_TICKET_IDを必須にしてください。 - 次の操作には、2 名によるレビューを実施してください:
- アカウントの閉鎖
- 高価値番号の解放
- 本番環境におけるメッセージング/音声 Webhook の変更
CIS ベンチマーク(該当する場合)
- CIS Ubuntu Linux Benchmark v2.0.1:
- 設定ファイルの最小権限を徹底してください(
chmod 600) - 管理スクリプトの実行に対する監査ログを有効にしてください
- 設定ファイルの最小権限を徹底してください(
- CIS Docker Benchmark v1.5.0(管理ツールをコンテナで実行する場合):
- シークレットをイメージに埋め込まないでください
- root 以外のユーザーで実行してください
- 可能な場合、読み取り専用ファイルシステムを使用してください
API リクエストの完全性
- 独自の自動化には、冪等性のパターンを使用してください:
- リソースを作成する前に、存在するかどうかを確認する
- 対応関係(サブアカウント名 → SID)を永続ストアに保存する
- Webhook では署名を検証し、厳密な解析を徹底してください。
パフォーマンスのチューニング
一括一覧取得とローカルでの結合により API 呼び出しを削減する
変更前:
- サブアカウントごとに、番号、使用状況、サービスを個別に一覧取得します(N×M 回の呼び出し)。
変更後:
- アカウント一覧を一度キャッシュし、同時実行数に上限を設けて並列処理し、HTTP セッションを再利用します。
期待される効果:
- 100 以上のサブアカウントを持つフリートで、3~10 倍高速になります。
20429 Rate limit exceededが発生する可能性を低減します。
Python のパターン(requests セッション + 同時実行数の制限):
import os
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from twilio.rest import Client
client = Client(os.environ["TWILIO_ACCOUNT_SID"], os.environ["TWILIO_AUTH_TOKEN"])
def fetch_usage(acct_sid: str):
sub = Client(os.environ["TWILIO_ACCOUNT_SID"], os.environ["TWILIO_AUTH_TOKEN"], account_sid=acct_sid)
recs = sub.usage.records.list(category="sms", granularity="daily", limit=30)
return acct_sid, sum(float(r.price or 0) for r in recs)
accounts = client.api.accounts.list(limit=200)
with ThreadPoolExecutor(max_workers=8) as ex:
futs = [ex.submit(fetch_usage, a.sid) for a in accounts]
for f in as_completed(futs):
sid, total = f.result()
print(sid, total)
time.sleep(0.05)
ジオマッチングとプーリングを備えた Messaging Services を使用する
- 番号を Messaging Service に集約します。
- ジオマッチングを有効にして、地域間のキャリア手数料を抑えます。
- 会話形式のフローで配信性を高めるには、スティッキー送信者を使用します。
期待される効果:
- 一部の地域でメッセージあたりのコストを削減できます。
- 単一の番号から送信する場合と比べて、スループットと配信性が向上します。
Webhook の処理:迅速な ACK と非同期処理
- HTTP 204/200 を 200 ミリ秒未満で返します。
- Kafka/SQS/PubSub にエンキューし、非同期で処理します。
期待される効果:
- Webhook の再試行と重複処理を防止します。
- トラフィックの急増時も安定性を保てます。
高度なトピック
サブアカウントを安全に閉鎖する手順(本番環境)
- サブアカウントを一時停止します(
status=suspended)。 - インベントリのスナップショットを取得します:
- 番号
- Messaging Services と電話番号プール
- 音声アプリ/Webhook URL
- トラフィックを排出します:
- アプリで送信を無効にする
- スケジュール済みジョブがサブアカウントを対象としていないことを確認する
- 番号を解放します(または他社へ移転します)。
- 24 時間にわたって使用状況がほぼゼロまで低下することを確認します。
- サブアカウントを閉鎖します。
番号の解放に関する依存関係
番号を解放する前に:
- Messaging Service のプールから削除します。
- 音声アプリで発信者 ID として設定されていないことを確認します。
- Verify で参照されていないことを確認します(カスタムチャネルの送信者として使用している場合)。
- コンプライアンスバンドルで必要とされていないことを確認します(地域によって異なります)。
複数リージョンにまたがる Twilio のエッジ
Twilio はリージョン/エッジをサポートしており、CLI プロファイルで region と edge を設定できます。
- レイテンシに敏感な操作では、リージョン/エッジを統一してください。
- 管理操作では、リージョンの不一致が致命的な問題になることは通常ありませんが、デバッグが複雑になる場合があります。
管理者レベルでの STOP/オプトアウトの処理
- STOP の処理は主にアプリケーションレベルと Messaging Service の設定で行います。
- 管理者の責務:
- インバウンド Webhook が設定され、到達可能であることを確認する
- オプトアウトキーワードが誤って上書きされていないことを確認する
- コンプライアンスログを保持する
SHAKEN/STIR の注意点
- 自身が所有する Twilio 番号を発信者番号として使用することは、高い認証レベルを得るために必要ですが、それだけで十分とは限りません。
- 管理していない番号を発信者番号として動的に設定することは避けてください。
- 応答率やスパム判定を監視し、利用可能な場合は通信事業者の分析データと照合してください。
SendGrid との連携に関する考慮事項
組織で SendGrid を使用している場合:
- テナント/環境ごとに Twilio のサブアカウントと SendGrid のサブユーザーを揃えてください。
- バウンスやスパムへの対応によってトランザクションメールに支障が出ないようにしてください。
- マーケティング用とトランザクション用で IP プールを分け、IP を段階的にウォームアップしてください。
使用例
1) サブアカウントを作成し、基本の Webhook を設定して、インベントリに記録する
サブアカウントを作成します:
twilio api:core:accounts:create --friendly-name "prod-tenant-acme" -o json | jq -r '.sid'
マッピングを保存します(ローカルファイルの例):
./inventory/twilio_subaccounts.json
mkdir -p inventory
twilio api:core:accounts:list -o json --limit 200 > inventory/twilio_subaccounts.json
電話番号を購入し、Webhook を設定します:
twilio api:core:incoming-phone-numbers:create \
--phone-number "+14155552671" \
--friendly-name "prod-acme-primary" \
--sms-url "https://api.example.com/twilio/sms/inbound" \
--sms-method POST \
--status-callback "https://api.example.com/twilio/sms/status" \
--status-callback-method POST \
--voice-url "https://api.example.com/twilio/voice/inbound" \
--voice-method POST \
-o json
2) 不正利用が疑われる場合に、チケットによる強制適用を伴ってサブアカウントを停止する
停止します:
export CHANGE_TICKET_ID="INC-20481"
export CHANGE_REASON="Suspected SMS pumping; usage spike 4x baseline"
twilio api:core:accounts:update --sid YOUR_ACCOUNT_SID --status suspended -o json
ステータスを確認します:
twilio api:core:accounts:fetch --sid YOUR_ACCOUNT_SID -o json | jq -r '.status'
3) サブアカウント全体の毎日の使用状況を集計する(JSON → CSV)
サブアカウントを一覧表示します:
twilio api:core:accounts:list -o json --limit 200 > /tmp/accounts.json
SID を抽出します:
jq -r '.[].sid' /tmp/accounts.json > /tmp/account_sids.txt
使用状況(毎日の SMS)をループ処理し、CSV を出力します:
echo "account_sid,total_price_usd" > /tmp/sms_usage.csv
while read -r sid; do
total="$(twilio api:core:usage:records:list --category sms --start-date 2026-02-20 --end-date 2026-02-20 --granularity daily -o json \
| jq '[.[].price | tonumber] | add // 0')"
echo "$sid,$total" >> /tmp/sms_usage.csv
sleep 0.2
done < /tmp/account_sids.txt
4) 電話番号を Messaging Service のプールに移行する
サービスを作成します:
twilio api:messaging:v1:services:create \
--friendly-name "prod-us-messaging" \
--sticky-sender true \
--smart-encoding true \
-o json | jq -r '.sid'
電話番号を追加します:
export MG_SID="YOUR_MG_SID"
for pn in PNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa PNbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; do
twilio api:messaging:v1:services:phone-numbers:create \
--service-sid "$MG_SID" \
--phone-number-sid "$pn" \
-o json
done
5) 使用していない電話番号を安全に解放する(事前チェック+削除)
フレンドリーネームのフィルターを使用して電話番号を一覧表示します(クライアント側):
twilio api:core:incoming-phone-numbers:list -o json --limit 200 \
| jq -r '.[] | select(.friendlyName | test("deprecated")) | .sid + " " + .phoneNumber'
削除します:
twilio api:core:incoming-phone-numbers:remove --sid PNXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6) Webhook エンドポイントを手早く検証する(TLS+HTTP)
TLS を確認します:
openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null | openssl x509 -noout -dates -issuer -subject
HTTP のヘルスチェック:
curl -sS -o /dev/null -w "%{http_code}\n" https://api.example.com/twilio/sms/status/health
クイックリファレンス
| タスク | コマンド | 主なフラグ |
|---|---|---|
| サブアカウントを一覧表示 | twilio api:core:accounts:list | --limit, -o json |
| サブアカウントを作成 | twilio api:core:accounts:create | --friendly-name |
| 停止/再有効化 | twilio api:core:accounts:update | --sid, `--status suspended |
| アカウントを閉鎖 | twilio api:core:accounts:update | --status closed |
| 毎日の使用状況 | twilio api:core:usage:records:list | --category, --start-date, --end-date, --granularity |
| 電話番号を一覧表示 | twilio api:core:incoming-phone-numbers:list | --limit, --properties |
| 電話番号を購入 | twilio api:core:incoming-phone-numbers:create | --phone-number, --friendly-name |
| 電話番号の Webhook を更新 | twilio api:core:incoming-phone-numbers:update | --sms-url, --status-callback, --voice-url |
| 電話番号を解放 | twilio api:core:incoming-phone-numbers:remove | --sid |
| 利用可能な電話番号を検索 | twilio api:core:available-phone-numbers:local:list | --iso-country, --in-region, --sms-enabled, --voice-enabled |
グラフ上の関係
DEPENDS_ON
[email protected][email protected][email protected][email protected][email protected]- 安全なシークレットストレージ(Vault/ASM/GSM)
COMPOSES
twilio-messaging(ステータスコールバック、STOP 処理、10DLC、フリーダイヤル番号の認証)twilio-voice(TwiML アプリ、SIP トランキング、録音/文字起こし、IVR ステートマシン)twilio-verify(Verify V2、Fraud Guard、レート制限)sendgrid-admin(テンプレート、受信メールの解析、IP ウォームアップ、バウンス/スパム対応)studio-admin(Flow のエクスポート/インポート、REST Trigger API、A/B テスト)
SIMILAR_TO
aws-organizations-admin(アカウントのライフサイクル+ガードレール)gcp-resource-manager-adminstripe-admin(課金/使用状況の監視パターン)okta-admin(監査/変更管理のパターン)