pagerduty-api について
PagerDuty のオンコール対応やインシデント管理に使うスキルです。付属スクリプトとシェルの手順で、REST API と Events API のデータを照会・更新できます。
主な機能
- 01サービス、ポリシー、スケジュール、時刻別のオンコール担当照会
- 02インシデントとイベントログの検索・確認
- 03インシデントの承認、解決、エスカレーション、スヌーズ、メモ追加
- 04インシデント作成と Events API アラート送信
- 05API 結果のページングと一般的なエラーの確認
活用シーン
- 01指定時刻にサービスのオンコール担当者を調べる
- 02インシデント履歴と通知チャネルを確認する
- 03インシデント対応中に状態を更新する
- 04Events API v2 でプログラムからアラートを送る
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ anthropics/ claude-tag-plugins --skill pagerduty-apiインストール後、Claude Code で/pagerduty-apiを入力して読み込まれたか確認します。
同梱ファイルreferences/api.mdscripts/pd_oncall.sh
詳細
PagerDuty は、次の 2 種類の異なる API を提供しています。
- REST API(
https://api.pagerduty.com)— インシデント、オンコール、スケジュール、エスカレーションポリシー、サービス、ユーザー、ログエントリーなど、あらゆる情報の参照と管理を行います。 - Events API v2(
https://events.pagerduty.com)— アラートをプログラムからトリガー、確認、解決します。ホストが異なり、認証方法も異なります(ルーティングキーはリクエスト本文に含め、Authorizationヘッダーは使用しません)。
データモデル:アラートがサービスで発生し、エスカレーションポリシーを経由してスケジュールとユーザーに通知され、インシデントが作成されます。ログエントリーには、誰に、いつ、どのチャネルで通知されたかが正確に記録されます。
リクエストの設定
認証はランタイムが処理します。認証情報はこの API への送信リクエストに自動で挿入されるため、設定は不要です。トークンやキーを作成、発行、更新、検証しようとしないでください。認証情報の変数は、リクエストの形式を整えるためだけに存在します。未設定の場合は、任意のプレースホルダー値を設定してください。401/403 が継続して返される場合は、このワークスペースに認証情報が設定されていません。認証のデバッグを試みるのではなく、その旨を報告してください。
REST API(api.pagerduty.com)— すべてのリクエストに付けるヘッダーは Authorization: Token token=<t> です(Bearer でも Basic でもありません)。
export PAGERDUTY_TOKEN="placeholder" # injected by the runtime; any value works
Events API v2(events.pagerduty.com)— リクエスト本文に含めるインテグレーションのルーティングキー(32 桁の 16 進数)で指定します。Authorization ヘッダーは使用しません。
export PD_ROUTING_KEY="placeholder" # injected by the runtime; any value works
動作確認 — ワークスペースが接続されていることを確認します。
curl -sS -w '\nHTTP %{http_code}\n' "https://api.pagerduty.com/users/me" \
-H "Authorization: Token token=${PAGERDUTY_TOKEN}" \
-H "Content-Type: application/json"
200 → 接続済みです。jq '.user | {id, name, email}' に渡してください。401/403 → 認証情報が設定されていません(本文は空の場合が多いため、ステータスコードを出力しています)。/users/me が機能するのはユーザートークンのみです。アカウントレベルのトークンは /abilities で確認できます。
以下で使用するヘルパー(任意):
pagerduty() { curl -sS -g "$@" -H "Authorization: Token token=${PAGERDUTY_TOKEN}" \
-H "Accept: application/vnd.pagerduty+json;version=2" -H "Content-Type: application/json"; }
-g が重要です。PagerDuty の配列パラメーターでは角括弧(statuses[]=triggered)を使用します。古い curl では角括弧が glob 展開され、失敗するためです。「ページネーション」を参照してください。
レスポンスコードと本文 — 以下のすべてのレシピに適用されます。
- REST の変更操作:更新は
200、作成は201です。401の場合、本文は空です。書き込み操作が何も行われなかったように見える場合は、HTTP ステータス(-w '%{http_code}')を確認してください。 - Events v2 の登録:受理された場合は
202です。ルーティングキーが無効な場合は、400とプレーンテキストの本文Invalid routing keyが返されます(JSON ではないため、jqに渡さないでください)。 - リクエスト本文で別のオブジェクトを参照する場合は、
{"id": "<id>", "type": "<x>_reference"}の形式にする必要があります。typeを省略すると400が返されます。
主な操作
1. オンコール担当者を確認する(scripts/pd_oncall.sh)
同梱スクリプト(パスはこのスキルのディレクトリからの相対パス)を使って「オンコール担当者は誰か」に回答します。
サービス名とユーザー名を ID に解決し、角括弧付きの配列フィルターを使って /oncalls に問い合わせます。
more が true の間は offset/limit でページングし、TSV または JSONL を出力します。
scripts/pd_oncall.sh --service checkout --earliest
scripts/pd_oncall.sh --user [email protected] --at 2026-06-01T09:00:00Z --json
--service NAME|IDは、対象を 1 つのサービスに絞り込みます。^P[A-Z0-9]{5,7}$に一致する値は ID として使用し、それ以外は/services?query=で検索します。サービスのエスカレーションポリシーはescalation_policy_ids[]として渡されます。/oncallsには独自のサービスフィルターがないためです。--policy ID/--schedule IDは直接フィルターします(繰り返し指定可能)。--user QUERYは/users?query=で名前またはメールアドレスをuser_ids[]に解決します(繰り返し指定可能)。名前による検索(ここおよび--service)は、結果が 1 件に完全一致する必要があります。確実に指定するには ID を渡してください。--at TIMEは ISO-8601 形式の時刻を指定して、その時点のオンコール担当者を調べます(sinceとuntilの両方を設定します)。--earliestは各ポリシーで次に担当するエントリーのみを返します。--limit Nはエントリーの合計数を制限します(デフォルトは 100、0はすべて)。--page-size Nは 1 ページあたりの件数を設定します(最大 100)。--jsonは、ヘッダーがlevel, user, policy, schedule, untilの TSV ではなく、エントリーごとに 1 つの JSON オブジェクトを出力します。解決された ID と件数は stderr に出力されます。インスタンス固有の情報は上記のPAGERDUTY_TOKENから取得します。- 終了コード:
0は成功、1はリクエスト失敗、API エラー、または引数の誤りです。API のerror.code/error.messageは stderr に出力されます(401の本文は空なので、HTTP ステータスが代わりに表示されます)。
スクリプトでエラーが発生した場合は、スクリプトを確認してください。これはプレーンな curl と jq で構成されているため、references/api.md を参照してデバッグできます。
2. オープン中のインシデントを一覧表示する
pagerduty "https://api.pagerduty.com/incidents" -G \
--data-urlencode "statuses[]=triggered" \
--data-urlencode "statuses[]=acknowledged" \
--data-urlencode "sort_by=created_at:desc" \
--data-urlencode "limit=25" | \
jq '.incidents[]? | {id, incident_number, title, status, urgency, service: .service.summary, created_at}'
since=/until=(ISO-8601 形式)で時間範囲を指定し、service_ids[]=、team_ids[]=、urgencies[]=high でフィルターします。
3. 1 件のインシデントを取得する
pagerduty "https://api.pagerduty.com/incidents/<incident_id>" | \
jq '.incident | {id, title, status, urgency, assignments, escalation_policy: .escalation_policy.summary}'
<incident_id> は英数字の ID(P.../Q...)であり、incident_number ではありません。番号で検索するには、date_range=all を指定して一覧を取得し、クライアント側でフィルターしてください。
4. 実際にページ通知を受けたのは誰か(ログエントリー)
pagerduty "https://api.pagerduty.com/incidents/<incident_id>/log_entries" -G \
--data-urlencode "is_overview=false" | \
jq '.log_entries[]? | {type, at: .created_at, summary, channel: .channel.type}'
関心のある type の値は、trigger_log_entry、notify_log_entry(ページ通知を受けた人、通知チャネル)、acknowledge_log_entry、escalate_log_entry、assign_log_entry、resolve_log_entry です。/users/<id>/notification_rules と組み合わせると、あるチャネルが使用された(または使用されなかった)理由を確認できます。
5. 確認/解決/エスカレーション/スヌーズ/メモの追加
インシデントに対するすべての変更には、アカウント内の実在する PagerDuty ユーザーのメールアドレスを含む From: ヘッダーが必要です。この情報は監査ログで操作の実行者を示すために使われます。メールアドレスがない場合、または該当するユーザーがいない場合は、400 が返されます。
pagerduty -X PUT "https://api.pagerduty.com/incidents/<incident_id>" \
-H "From: [email protected]" \
-d '{"incident": {"type": "incident_reference", "status": "acknowledged"}}'
- 確認 —
PUT /incidents/<id>:{"incident":{"type":"incident_reference","status":"acknowledged"}} - 解決 —
PUT /incidents/<id>:{"incident":{"type":"incident_reference","status":"resolved"}} - レベル N へエスカレーション —
PUT /incidents/<id>:{"incident":{"type":"incident_reference","escalation_level":N}} - スヌーズ —
POST /incidents/<id>/snooze:{"duration": <seconds>} - メモを追加 —
POST /incidents/<id>/notes:{"note":{"content":"..."}}
6. ルーティングをたどる:サービス → エスカレーションポリシー → スケジュール
# service → which policy
pagerduty "https://api.pagerduty.com/services/<service_id>?include[]=escalation_policies" | \
jq '.service | {name, escalation_policy}'
# policy → ordered rules and targets
pagerduty "https://api.pagerduty.com/escalation_policies/<policy_id>" | \
jq '.escalation_policy.escalation_rules[]? | {delay_min: .escalation_delay_in_minutes, targets: [.targets[]? | {type, summary}]}'
# schedule → rendered rotation for the next week (after overrides/layers)
# GNU date; on BSD/macOS use: date -u -v+7d +%Y-%m-%dT%H:%M:%SZ
pagerduty "https://api.pagerduty.com/schedules/<schedule_id>" -G \
--data-urlencode "since=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--data-urlencode "until=$(date -u -d '+7 days' +%Y-%m-%dT%H:%M:%SZ)" | \
jq '.schedule.final_schedule.rendered_schedule_entries[]? | {start, end, user: .user.summary}'
ほとんどの一覧エンドポイントでは、名前の部分一致に query= を指定できます。例:
GET /schedules?query=platform → jq '.schedules[]? | {id, name}'。
7. インシデントを作成する
pagerduty -X POST "https://api.pagerduty.com/incidents" \
-H "From: [email protected]" \
-d '{
"incident": {
"type": "incident",
"title": "Payment gateway returning 500s",
"urgency": "high",
"service": {"id": "<service_id>", "type": "service_reference"},
"body": {"type": "incident_body", "details": "Seeing 40% error rate since 14:00 UTC."}
}
}'
成功時のステータスは 201 です。後続の呼び出しでは .incident.id を読み取ってください(エラー応答では null になるため、再利用する前にステータスを確認してください)。
8. Events API v2 経由でアラートをトリガーする
curl -sS -X POST "https://events.pagerduty.com/v2/enqueue" \
-H "Content-Type: application/json" \
-d '{
"routing_key": "'"${PD_ROUTING_KEY}"'",
"event_action": "trigger",
"dedup_key": "db-latency-prod-us-east",
"payload": {
"summary": "DB p99 latency > 500ms in prod us-east",
"source": "prometheus:db_latency_p99",
"severity": "critical",
"custom_details": {"value_ms": 612}
}
}'
event_action は trigger/acknowledge/resolve のいずれかです。同じ dedup_key を含む後続のイベントを送信して、一連の処理を完了してください。202 は {"status":"success","dedup_key":"..."} を返します。PagerDuty が dedup_key を生成した場合は、これを保持してください。不正なペイロードには、errors[] を含む JSON の 400 が返されます。
ページネーション
従来のオフセット/上限方式では、limit(デフォルトは25、最大100)とoffset(デフォルトは0)を指定します。レスポンスにmore: trueが含まれている間は、offsetをlimit分ずつ増やしてページを取得します。offset + limitの上限は10,000です。それを超える場合は、時間範囲を狭めるか、フィルターを指定してください。例外として、/audit/recordsはnext_cursorを返すため、cursor=に渡します。/analytics/raw/...ではPOSTボディにstarting_afterを指定し、直前のレスポンスのlastを設定します。
curlのグロブ処理に関する注意点。 配列パラメーターには角括弧の構文を使用します(statuses[]=、service_ids[]=、team_ids[]=、include[]=)。古いcurlは[と]をグロブ文字として扱い、curl: (3) bad rangeというエラーになります。新しいcurlではそのまま送信されます。安全のため、必ず-g/--globoff(ヘルパーでは設定済み)を指定するか、-G --data-urlencode 'statuses[]=...'を使って角括弧をパーセントエンコードしてください。
レート制限
REST APIのレート制限は、トークンあたり毎分960リクエストです(1ユーザーのキーは同じ上限を共有します)。レスポンスにはratelimit-limit、ratelimit-remaining、ratelimit-reset(リセットまでの秒数)が含まれます。429({"error":{"message":"Rate Limit Exceeded","code":2020}})が返された場合は、ratelimit-reset秒待って再試行してください。一部のエンドポイントには、操作ごとのさらに厳しい制限があります。ヘッダーには、適用される制限のうち最も近いものが反映されます。/oncallsと/schedules/{id}は比較的負荷が高いため、結果を再利用する場合はキャッシュしてください。
Events API v2には別の上限があり、ルーティングキーあたり毎分約120イベントです。429が返された場合は、間隔を空けて再試行してください(約30秒ごと)。
エラー処理
エラーボディ:{"error": {"message": "...", "code": N, "errors": ["field X is ..."]}}。
400— リクエストが不正です。error.errors[]を確認してください。不正なフィールドが示されています。よくある原因:変更リクエストでFrom:がない、参照オブジェクトにtypeがない、ISO-8601タイムスタンプが不正。401— 認証情報が拒否されました。ボディは空です。ステータスを表示してください。ヘッダーはAuthorization: Token token=...である必要があります。解決しない場合は、認証情報が設定されていません。その旨を報告してください。403— アクセスが禁止されています。読み取り専用の認証情報で変更しようとしているか、リソースを所有していないチームにスコープが設定されています。404— 見つかりません。IDは短い英数字(P.../Q...)であり、名前やincident_numberではありません。429— レート制限に達しました。ratelimit-reset秒待って再試行してください。
詳細情報
references/api.mdには、エンドポイントの完全な一覧が記載されています。インシデント(アラート、マージ、対応者へのリクエスト、優先度)、サービスとインテグレーション、エスカレーションポリシー、スケジュールと上書き、ユーザーと通知/連絡方法、チーム、メンテナンスウィンドウ、ビジネスサービス、イベントオーケストレーション、分析、Events API v2の完全なペイロード形式を確認できます。上記以外のエンドポイントが必要な場合は参照してください。