外部API リファレンス
SonaeTocのREST APIを使って、プログラム・CI/CDパイプライン・AIエージェントから監視を操作できます。 ベースURL: https://sonaetoc.com/v1
クイックスタート
APIキーを発行
最初のリクエストを送信
curl https://sonaetoc.com/v1/tenant \ -H "Authorization: Bearer sonaetoc_live_YOUR_API_KEY"
モニターを作成
curl -X POST https://sonaetoc.com/v1/monitors \
-H "Authorization: Bearer sonaetoc_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "本番トップページ",
"type": "visual",
"url": "https://example.com",
"interval_minutes": 60,
"visual_config": {
"viewport": { "width": 1920, "height": 1080 },
"threshold": 0.1,
"wait_for": "networkidle",
"full_page": true,
"delay_ms": 1000
}
}'認証
すべてのリクエストに Authorization: Bearer ヘッダーが必要です。
Authorization: Bearer sonaetoc_live_xxxxxxxxxx
スコープ
キー作成時にスコープを制限できます。デフォルトは全権限です。
| スコープ | 権限 |
|---|---|
| monitors:read | モニター設定の閲覧 |
| monitors:write | モニターの作成・更新・削除 |
| monitors:execute | 手動実行のトリガー |
| results:read | 監視結果の閲覧・スナップショット比較 |
| crawls:read | クロール結果の閲覧 |
| crawls:write | クロールジョブの作成・削除 |
| notifications:read | 通知設定の閲覧 |
| notifications:write | 通知設定の作成・更新・削除 |
| ai_checks:read | AIチェックジョブ・指摘の閲覧 |
| ai_checks:write | AIチェックジョブの作成・削除 |
| ai_checks:execute | AIチェック監視の手動実行 |
| members:read | メンバー一覧の閲覧 |
| members:write | メンバーのロール変更・削除 |
| invitations:read | 招待一覧の閲覧 |
| invitations:write | 招待の作成・取消・再送 |
レスポンス形式
日時はすべて ISO 8601(UTC)です。
{
"data": { "id": "mon_xxx", "name": "..." },
"meta": { "request_id": "req_abc123" }
}{
"data": [ ... ],
"meta": {
"request_id": "req_abc123",
"has_more": true,
"next_cursor": "eyJ..."
}
}{
"error": {
"code": "validation_error",
"message": "name is required (1-100 chars)."
},
"meta": { "request_id": "req_abc123" }
}モニター
/v1/monitorsmonitors:readモニター一覧を取得
| パラメータ | 型 | 説明 |
|---|---|---|
| type | string | visual / healthcheck / motion / ai_check |
| status | string | ok / changed / error |
| is_active | boolean | 有効/無効でフィルタ |
| limit | number | 取得件数(デフォルト20、最大100) |
| cursor | string | ページネーションカーソル |
| include_count | boolean | trueで total_count を返却 |
/v1/monitorsmonitors:writeモニターを作成(type=ai_check は Pro プラン以上)
{
"name": "API /health",
"type": "healthcheck",
"url": "https://api.example.com/health",
"interval_minutes": 15,
"healthcheck_config": {
"method": "GET",
"expected_status": 200,
"timeout_ms": 10000
}
}{
"name": "ログインフロー",
"type": "motion",
"url": "https://example.com/login",
"interval_minutes": 1440,
"motion_config": {
"viewport": { "width": 1920, "height": 1080 },
"threshold": 0.5,
"steps": [
{ "action": "fill", "selector": "#email", "value": "test@example.com" },
{ "action": "fill", "selector": "#password", "value": "secret", "is_secret": true },
{ "action": "click", "selector": "#submit", "wait_for_navigation": true }
]
}
}{
"name": "本番トップページのAIチェック",
"type": "ai_check",
"url": "https://example.com",
"interval_minutes": 1440,
"schedule_type": "interval",
"ai_check_config": {
"selection": { "preset": "chiku", "enabled_items": [] },
"viewport": { "width": 1920, "height": 1080 },
"provider_model": "gemini-3.1-flash-lite",
"compare_with_previous": false
}
}schedule_type: "none" を指定すると「手動実行のみ」の監視として作成され、サーバー側で初回ジョブを自動発火します(interval_minutes は省略可)。スケジュール総量が月次クォータの 80% を超えると data.warning が返却され、100% を超えると 403 plan_limit_exceeded で拒否されます。
/v1/monitors/{id}monitors:readモニター詳細を取得
/v1/monitors/{id}monitors:writeモニターを更新(シャローマージ、配列は全置換)
/v1/monitors/{id}monitors:writeモニターを削除(結果も自動削除)
/v1/monitors/{id}/executemonitors:execute手動実行をトリガー(202 Accepted)
/v1/monitors/{id}/activatemonitors:writeモニターを有効化
/v1/monitors/{id}/deactivatemonitors:writeモニターを無効化
監視結果
/v1/monitors/{id}/resultsresults:read結果一覧を取得
| パラメータ | 型 | 説明 |
|---|---|---|
| status | string | ok / changed / error |
| from | string | 開始日時(ISO 8601) |
| to | string | 終了日時(ISO 8601) |
| limit | number | 取得件数(デフォルト20、最大100) |
| cursor | string | ページネーションカーソル |
レスポンスはモニタータイプに応じて異なります:
{
"id": "result_xyz",
"monitor_id": "mon_abc",
"status": "changed",
"is_manual": false,
"visual": {
"screenshot_url": "https://storage...(署名付き)",
"previous_screenshot_url": "https://storage...",
"diff_percentage": 3.5,
"pixel_count": 12400
},
"executed_at": "2026-04-05T10:00:00Z"
}{
"id": "result_hc1",
"monitor_id": "mon_hc",
"status": "ok",
"healthcheck": {
"status_code": 200,
"response_time_ms": 245,
"error_message": null
},
"executed_at": "2026-04-05T10:00:00Z"
}{
"id": "result_mt1",
"monitor_id": "mon_mt",
"status": "changed",
"motion": {
"video_url": "https://storage...(署名付き)",
"total_diff_percentage": 3.5,
"steps_executed": 4,
"steps_failed": 0,
"frames": [
{ "step_index": 0, "label": "メール入力", "diff_percentage": 0, "status": "ok" },
{ "step_index": 2, "label": "ログイン", "diff_percentage": 3.5, "status": "changed" }
]
},
"executed_at": "2026-04-05T10:00:00Z"
}/v1/monitors/{id}/results/latestresults:read最新結果を1件取得(レスポンスは上記と同形式)
/v1/monitors/{id}/results/{resultId}results:read結果詳細を取得(レスポンスは上記と同形式)
/v1/monitors/{id}/statsresults:read統計情報を取得
| パラメータ | 型 | 説明 |
|---|---|---|
| period | string | 24h / 7d / 30d(デフォルト 7d) |
{
"monitor_id": "mon_abc",
"period": "7d",
"total_checks": 168,
"status_counts": { "ok": 165, "changed": 2, "error": 1 },
"uptime_percentage": 99.4,
"avg_response_time_ms": 1250,
"avg_diff_percentage": 0.03,
"max_diff_percentage": 5.2
}クロール
/v1/crawlscrawls:readクロールジョブ一覧
/v1/crawlscrawls:writeクロールを開始(202 Accepted)
{
"name": "example.com 構造チェック",
"url": "https://example.com",
"config": {
"max_depth": 3,
"max_pages": 100,
"rendering": "javascript"
}
}/v1/crawls/{id}crawls:readジョブ詳細・進捗
/v1/crawls/{id}/pagescrawls:readクロール済みページ一覧
/v1/crawls/{id}crawls:writeジョブを削除
通知設定
/v1/notificationsnotifications:read通知設定一覧
/v1/notificationsnotifications:write通知設定を作成
{
"name": "Slack通知",
"type": "slack",
"events": ["visual_changed", "healthcheck_down"],
"slack_config": {
"webhook_url": "https://hooks.slack.com/services/xxx/yyy/zzz"
}
}/v1/notifications/{id}notifications:write通知設定を更新
/v1/notifications/{id}notifications:write通知設定を削除
/v1/notifications/{id}/testnotifications:writeテスト通知を送信
AIチェック
Pro プラン以上で利用可能。月次クォータ(Pro: 50回 / Enterprise: 500回)を消費します。AIチェック「監視」の CRUD は /v1/monitors(type=ai_check)を使い、ここではジョブ・指摘の取得と単発実行を扱います。
/v1/ai-checks/jobsai_checks:readジョブ一覧を取得
| パラメータ | 型 | 説明 |
|---|---|---|
| status | string | queued / running / completed / error |
| source_monitor_id | string | 起動元 monitor ID |
| source_result_id | string | 連動元の result ID |
| trigger | string | manual / monitor_event / scheduled |
| from | string | 開始日時(ISO 8601) |
| to | string | 終了日時(ISO 8601) |
| limit | number | デフォルト20、最大100 |
| cursor | string | ページネーションカーソル |
/v1/ai-checks/jobsai_checks:write単発ジョブを作成(monitor 不要・202 Accepted)
{
"url": "https://example.com",
"preset": "chiku",
"viewport": { "width": 1920, "height": 1080 },
"provider_model": "gemini-3.1-flash-lite"
}preset: shou(全項目)/ chiku(P0+P1)/ ume(P0のみ)/ custom(custom_enabled_items 必須)。gemini-2.5-pro は Enterprise のみ。
/v1/ai-checks/jobs/{jobId}ai_checks:readジョブ詳細(スクショURL等含む)
/v1/ai-checks/jobs/{jobId}ai_checks:writeジョブ削除(findings・スクショもカスケード削除)
/v1/ai-checks/jobs/{jobId}/findingsai_checks:read指摘一覧
| パラメータ | 型 | 説明 |
|---|---|---|
| category | string | ui_ux / seo / accessibility / security 等 |
| severity | string | critical / warning / info |
| limit | number | デフォルト100、最大500 |
| cursor | string | ページネーションカーソル |
/v1/monitors/{monitorId}/ai-checkai_checks:executeAIチェック監視の手動実行(10分クールダウン)
スナップショット比較
/v1/monitors/{monitorId}/compareresults:read同一 monitor の任意2件の結果を並べて比較(visual / motion)
| パラメータ | 型 | 説明 |
|---|---|---|
| result_a | string | 古い方の result ID(必須) |
| result_b | string | 新しい方の result ID(必須) |
{
"monitor_id": "mon_abc",
"monitor_type": "visual",
"result_a": {
"id": "result_old",
"status": "ok",
"executed_at": "2026-04-04T10:00:00Z",
"screenshot_url": "https://storage..."
},
"result_b": {
"id": "result_new",
"status": "changed",
"executed_at": "2026-04-05T10:00:00Z",
"screenshot_url": "https://storage...",
"diff_percentage": 0.5
}
}メンバー
/v1/membersmembers:readメンバー一覧を取得
| パラメータ | 型 | 説明 |
|---|---|---|
| role | string | owner / editor / viewer でフィルタ |
| limit | number | デフォルト20、最大100 |
| cursor | string | ページネーションカーソル |
/v1/members/{memberId}members:writeロールを変更(editor / viewer)
{ "role": "viewer" }owner への昇格は不可。最後の owner を降格しようとすると 409 conflict を返します。
/v1/members/{memberId}members:writeメンバー削除(owner は削除不可)
招待
招待リンクは登録メールアドレスに送信されます。API レスポンスには token は含まれません。
/v1/invitationsinvitations:read招待一覧
| パラメータ | 型 | 説明 |
|---|---|---|
| status | string | pending / accepted / declined / expired / cancelled |
| limit | number | デフォルト20、最大100 |
| cursor | string | ページネーションカーソル |
/v1/invitationsinvitations:write招待を作成(メール送信)
{
"email": "newuser@example.com",
"role": "editor"
}Free プランは招待不可。1時間に10件までの作成レート制限あり。メール送信に失敗してもドキュメントは作成され、レスポンスに email_sent: false と message が含まれます。
/v1/invitations/{invitationId}invitations:read招待詳細
/v1/invitations/{invitationId}invitations:write招待を取消(accepted は取消不可)
/v1/invitations/{invitationId}/resendinvitations:write招待メールを再送(前回送信から10分のクールダウン)
テナント情報
/v1/tenantプラン・使用量・制限値を取得
{
"id": "tenant_abc",
"name": "My Company",
"plan": "pro",
"limits": {
"max_visual": 5, "max_healthcheck": 10,
"max_motion": 1, "max_crawls": 20,
"min_interval_minutes": 10,
"api_keys": 3,
"api_requests_per_hour": 60,
"api_requests_per_day": 500
},
"usage": {
"visual_count": 3, "healthcheck_count": 5,
"motion_count": 0, "crawls_this_month": 2,
"api_keys_count": 1, "api_requests_today": 42
}
}レート制限
| 制限 | Free | Pro | Enterprise |
|---|---|---|---|
| APIキー数 | 1 | 3 | 10 |
| リクエスト/時 | 30 | 60 | 300 |
| リクエスト/日 | 200 | 500 | 3,000 |
レスポンスヘッダー X-RateLimit-Remaining で残りリクエスト数を確認できます。 超過時は 429 が返り、X-RateLimit-Reset に再試行可能なUnixタイムスタンプが入ります。
エラーコード
| HTTP | code | 原因と対処 |
|---|---|---|
| 400 | validation_error | リクエストボディが不正。message を確認してフィールドを修正 |
| 400 | invalid_request | URLがプライベートIPに解決される等。SSRF対策 |
| 401 | unauthorized | APIキーが無効・期限切れ・未指定。Authorizationヘッダーを確認 |
| 403 | forbidden | スコープ不足。必要なスコープ付きのキーを使用 |
| 403 | plan_limit_exceeded | プラン上限に到達。不要なリソースを削除するかアップグレード |
| 404 | not_found | リソースが存在しない。IDを確認 |
| 429 | rate_limit_exceeded | レート制限超過。X-RateLimit-Reset まで待機 |
| 500 | internal_error | サーバーエラー。しばらく待って再試行 |
CI/CD連携パターン
デプロイ後にビジュアルチェックを自動実行し、差分が閾値を超えたらパイプラインを失敗させる例です。
- name: Visual regression check
env:
API_KEY: ${{ secrets.SONAETOC_API_KEY }}
MONITOR_ID: mon_xxxxxxxxxxxx
run: |
# 1. 手動実行をトリガー
curl -sf -X POST \
"https://sonaetoc.com/v1/monitors/$MONITOR_ID/execute" \
-H "Authorization: Bearer $API_KEY"
# 2. 結果が出るまで待機
sleep 30
# 3. 最新結果を取得して差分を確認
RESULT=$(curl -sf \
"https://sonaetoc.com/v1/monitors/$MONITOR_ID/results/latest" \
-H "Authorization: Bearer $API_KEY")
DIFF=$(echo "$RESULT" | jq -r '.data.visual.diff_percentage // 0')
echo "Visual diff: $DIFF%"
if (( $(echo "$DIFF > 5.0" | bc -l) )); then
echo "::error::Visual regression detected ($DIFF%)"
exit 1
fi冪等性(Idempotency-Key)
POSTリクエストに Idempotency-Key ヘッダーを付与すると、同じキーでの再リクエスト時にキャッシュされたレスポンスが返されます。ネットワークエラー時のリトライに安全です。
curl -X POST https://sonaetoc.com/v1/monitors \
-H "Authorization: Bearer sonaetoc_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-123" \
-d '{ ... }'ページネーション
一覧エンドポイントはカーソルベースのページネーションを使用します。meta.next_cursor を次のリクエストの cursor パラメータに渡します。
# 1ページ目 curl "https://sonaetoc.com/v1/monitors?limit=10" \ -H "Authorization: Bearer $API_KEY" # → meta.next_cursor: "eyJ..." # 2ページ目 curl "https://sonaetoc.com/v1/monitors?limit=10&cursor=eyJ..." \ -H "Authorization: Bearer $API_KEY"