HookSignal API ドキュメント
HookSignal APIを使用してWebhookを受信、管理、自動化します。包括的なガイドで統一されたWebhook通知ハブを構築しましょう。
概要
HookSignal APIは、複数のサービスからのWebhook通知を一元管理し、AI要約、スマートフィルタリング、エスカレーション機能を提供するRESTful APIです。
https://hooksignal.io/api/v1https://hooksignal.io/api/incoming/{token}特徴:
- 複数サービスのWebhookを単一のエンドポイントで受信
- 自動署名検証(HMAC-SHA256)
- AI による自動要約と内容抽出
- スマート通知ルール(タイトル、優先度、フィルタリング)
- エスカレーション設定(重大度別)
- リアルタイム通知配信(複数チャネル対応)
認証
HookSignal API は Bearer トークン認証を使用します。ダッシュボードから API キーを生成し、リクエストヘッダーに含めます。
- ダッシュボードの「プロジェクト設定」→「API キー」を開く
- 「新しい API キーを生成」をクリック
- キーをコピーして安全に保管(再表示不可)
- API リクエストで使用
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://hooksignal.io/api/v1/projects/your-project-id/logs⚠️ セキュリティ注意: API キーを公開しないでください。Git にコミットしないよう .gitignore に追加し、環境変数で管理してください。
Webhook の受信
Webhook トークンを使用してHookSignal にWebhook通知を送信します。各プロジェクトに固有のトークンが割り当てられます。
POST /api/incoming/{token}リクエストヘッダー
| ヘッダー | 説明 |
|---|---|
| Content-Type | application/json(必須) |
| X-Hub-Signature-256 | HMAC-SHA256 署名(オプション但し推奨) |
リクエストボディ
| フィールド | 型 | 説明 |
|---|---|---|
| title | string | 通知のタイトル(必須、最大200文字) |
| body | string | 通知の詳細内容(オプション) |
| level | string | 通知レベル: info, warning, error, critical, success(デフォルト: info) |
| source | string | Webhook ソース(例: github, slack, stripe) |
| リッチ通知フィールド(すべてオプション) | ||
| body_format | string | 本文の表示形式: markdown | plain(デフォルト: plain) |
| source_url | string | 元ソースの URL(例: PR、Issue、ダッシュボード) |
| image_url | string | プレビュー画像 URL |
| tags | string[] | 分類タグ(最大20個) |
| sender | object | 送信者情報: { name, avatar_url, url } |
| links | object[] | 関連リンク(最大10個): { label, url } |
| actions | object[] | アクションボタン(最大5個): { label, style, type, url, method } |
| fields | object[] | メタデータフィールド(最大20個): { label, value } |
レスポンス(成功時)
{
"id": "log_abc123def456",
"status": "accepted",
"timestamp": "2026-03-08T10:30:00Z"
}署名検証
HookSignal はリクエストの真正性を検証するため、HMAC-SHA256 署名を使用します。ダッシュボードで WebHook シークレットを確認し、署名を検証してください。
- リクエストボディをそのままテキストで取得(JSON 文字列)
- HMAC-SHA256 で署名を生成: hmac = HMAC-SHA256(body, secret)
- 署名を十六進数で符号化: signature = hex(hmac)
- X-Hub-Signature-256 ヘッダーと比較
const crypto = require('crypto');
function verifySignature(requestBody, signature, secret) {
const hmac = crypto
.createHmac('sha256', secret)
.update(requestBody)
.digest('hex');
return hmac === signature;
}
// 使用例
app.post('/webhook', (req, res) => {
const signature = req.headers['x-hub-signature-256'];
const secret = process.env.WEBHOOK_SECRET;
if (!verifySignature(req.rawBody, signature, secret)) {
return res.status(403).json({ error: 'Invalid signature' });
}
// 署名検証成功
console.log('Webhook received:', req.body);
res.json({ status: 'ok' });
});import hmac
import hashlib
def verify_signature(request_body, signature, secret):
hmac_gen = hmac.new(
secret.encode(),
request_body.encode(),
hashlib.sha256
)
return hmac.compare_digest(
hmac_gen.hexdigest(),
signature
)
# 使用例
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Hub-Signature-256')
secret = os.getenv('WEBHOOK_SECRET')
if not verify_signature(request.get_data(as_text=True), signature, secret):
return jsonify({'error': 'Invalid signature'}), 403
print('Webhook received:', request.json)
return jsonify({'status': 'ok'})通知レベル
HookSignal は通知を5つのレベルに分類し、優先度管理やエスカレーションを行います。
通常情報。定期的なレポートや更新など。
要注意。処理が遅延している、リソース使用率が高いなど。
エラー。API エラーやリクエスト失敗など。すぐに対応が必要。
致命的。システムダウンやセキュリティ侵害の可能性。
成功。デプロイ完了やバックアップ成功など。
リッチ通知
通常のテキスト通知に加えて、Markdown本文、送信者情報、タグ、関連リンク、アクションボタン、メタデータフィールドなど、リッチなコンテンツを含めることができます。すべてのリッチフィールドはオプションで、既存のペイロードとの後方互換性があります。
Markdown 本文
見出し・リスト・コードブロック対応
body_format: "markdown"
送信者 & タグ
アバター画像と分類タグで視認性向上
sender, tags
アクションボタン
リンク遷移やAPI呼び出しをワンクリックで
actions
| プロパティ | 型 | 説明 |
|---|---|---|
| label | string | ボタンラベル |
| style | string | primary | secondary | destructive |
| type | string | link(URL をブラウザで開く)| api(HookSignal サーバー経由でプロキシ実行) |
| url | string | 遷移先 URL または API エンドポイント(HTTPS のみ) |
| method | string | type: "api" 時の HTTP メソッド: GET | POST | PUT | DELETE(デフォルト: POST) |
curl -X POST https://hooksignal.io/api/incoming/your-token \
-H "Content-Type: application/json" \
-d '{
"title": "プルリクエスト #142 がマージされました",
"message": "## 変更内容\n\n- 認証フローをリファクタリング\n- Redis に移行\n\n**影響**: /api/auth/*",
"level": "success",
"body_format": "markdown",
"source_url": "https://github.com/your-org/repo/pull/142",
"tags": ["backend", "auth", "v2.5.0"],
"sender": {
"name": "田中太郎",
"avatar_url": "https://avatars.githubusercontent.com/u/12345",
"url": "https://github.com/tanaka-taro"
},
"links": [
{ "label": "PR を見る", "url": "https://github.com/your-org/repo/pull/142" },
{ "label": "CI ログ", "url": "https://github.com/your-org/repo/actions/runs/98765" }
],
"actions": [
{ "label": "本番デプロイ", "style": "primary", "type": "api", "url": "https://deploy.example.com/api/deploy", "method": "POST" },
{ "label": "リリースノート", "style": "secondary", "type": "link", "url": "https://github.com/your-org/repo/releases/new" },
{ "label": "ロールバック", "style": "destructive", "type": "api", "url": "https://deploy.example.com/api/rollback", "method": "POST" }
],
"fields": [
{ "label": "ブランチ", "value": "feature/auth → main" },
{ "label": "コミット数", "value": "12" },
{ "label": "変更ファイル", "value": "28 files (+1,204 / -567)" },
{ "label": "レビュー承認", "value": "2/2" }
]
}'{
"title": "週次レポートが生成されました",
"message": "2026年3月第2週のレポートが準備できました。",
"level": "info",
"source_url": "https://analytics.example.com/reports/weekly",
"links": [
{ "label": "レポートを見る", "url": "https://analytics.example.com/reports/weekly" }
],
"fields": [
{ "label": "PV", "value": "124,532" },
{ "label": "UU", "value": "45,891" },
{ "label": "前週比", "value": "+8.3%" }
]
}💡 ヒント: リッチフィールドはすべてオプションです。既存のシンプルなペイロードはそのまま動作します。必要なフィールドだけを追加して段階的に拡張できます。
レート制限
HookSignal は安定したサービス提供のため、リクエスト数を制限しています。
60 リクエスト / 分
クライアント IP ごとの制限
120 リクエスト / 分
トークン ID ごとの制限
HTTP 429 Too Many Requests レスポンスが返されます。
以下のヘッダーで制限情報を確認できます:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1678276800
Retry-After: 30ペイロード例
様々なサービスからのWebhook例を紹介します。
curl -X POST https://hooksignal.io/api/incoming/your-webhook-token \
-H "Content-Type: application/json" \
-d '{
"title": "デプロイが完了しました",
"body": "Production に v1.2.3 がリリースされました",
"level": "success",
"source": "vercel"
}'{
"title": "Push to main branch",
"body": "Commit: Fix auth bug\nAuthor: alice@example.com\nURL: https://github.com/...",
"level": "info",
"source": "github"
}{
"title": "TypeError in production",
"body": "Cannot read property 'map' of undefined\nFile: /app/utils.js:42\nURL: https://sentry.io/...",
"level": "critical",
"source": "sentry"
}{
"title": "Order #12345 completed",
"body": "Customer: John Doe\nTotal: $99.99\nShipping: Express",
"level": "success",
"source": "ecommerce-app"
}SDKとツール
curl や一般的なプログラミング言語を使用してHookSignal と連携できます。
curl -X POST \
https://hooksignal.io/api/incoming/your-webhook-token \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: your-signature" \
-d '{
"title": "Test Notification",
"body": "This is a test",
"level": "info"
}'const axios = require('axios');
async function sendWebhook(title, body, level = 'info') {
try {
const response = await axios.post(
'https://hooksignal.io/api/incoming/your-webhook-token',
{ title, body, level },
{
headers: {
'Content-Type': 'application/json',
}
}
);
console.log('Webhook sent:', response.data);
} catch (error) {
console.error('Error sending webhook:', error.message);
}
}
// 基本的な使用例
sendWebhook('Deployment Complete', 'v1.0.0 deployed to production', 'success');
// リッチ通知の例
async function sendRichWebhook() {
await axios.post(
'https://hooksignal.io/api/incoming/your-webhook-token',
{
title: 'Build Failed',
message: '## Error\n`Module not found`',
level: 'error',
body_format: 'markdown',
tags: ['ci', 'build'],
sender: { name: 'GitHub Actions' },
actions: [
{ label: 'Retry', style: 'primary', type: 'api',
url: 'https://api.github.com/actions/rerun', method: 'POST' },
{ label: 'View Logs', style: 'secondary', type: 'link',
url: 'https://github.com/org/repo/actions/runs/123' }
],
fields: [
{ label: 'Pipeline', value: 'CI / Build' },
{ label: 'Duration', value: '2m 34s' }
]
},
{ headers: { 'Content-Type': 'application/json' } }
);
}import requests
import json
def send_webhook(title, body, level='info'):
url = 'https://hooksignal.io/api/incoming/your-webhook-token'
payload = {
'title': title,
'body': body,
'level': level
}
headers = {
'Content-Type': 'application/json'
}
try:
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
print('Webhook sent:', response.json())
except requests.exceptions.RequestException as e:
print('Error sending webhook:', str(e))
# 使用例
send_webhook('Deployment Complete', 'v1.0.0 deployed to production', 'success')package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Webhook struct {
Title string `json:"title"`
Body string `json:"body"`
Level string `json:"level"`
}
func sendWebhook(title, body, level string) error {
webhook := Webhook{
Title: title,
Body: body,
Level: level,
}
payload, _ := json.Marshal(webhook)
resp, err := http.Post(
"https://hooksignal.io/api/incoming/your-webhook-token",
"application/json",
bytes.NewBuffer(payload),
)
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Println("Webhook sent:", resp.StatusCode)
return nil
}
// 使用例
func main() {
sendWebhook("Deployment Complete", "v1.0.0 deployed", "success")
}エラーレスポンス
エラー発生時は適切なHTTPステータスコードが返されます。
400
Bad Request
リクエストが無効です
401
Unauthorized
認証が必要です
403
Forbidden
署名検証に失敗しました
413
Payload Too Large
256KB を超えるペイロード
429
Too Many Requests
レート制限超過
500
Internal Server Error
サーバーエラー