外部API リファレンス

SonaeTocのREST APIを使って、プログラム・CI/CDパイプライン・AIエージェントから監視を操作できます。 ベースURL: https://sonaetoc.com/v1

クイックスタート

1

APIキーを発行

ダッシュボードの 設定 > APIキー管理 からキーを作成します。キーは作成時に一度だけ表示されます。
2

最初のリクエストを送信

curl
curl https://sonaetoc.com/v1/tenant \
  -H "Authorization: Bearer sonaetoc_live_YOUR_API_KEY"
3

モニターを作成

curl
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
    }
  }'
APIキーはパスワードと同じです。リポジトリにコミットせず、環境変数で管理してください。

認証

すべてのリクエストに 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:readAIチェックジョブ・指摘の閲覧
ai_checks:writeAIチェックジョブの作成・削除
ai_checks:executeAIチェック監視の手動実行
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" }
}

モニター

GET/v1/monitorsmonitors:read

モニター一覧を取得

パラメータ説明
typestringvisual / healthcheck / motion / ai_check
statusstringok / changed / error
is_activeboolean有効/無効でフィルタ
limitnumber取得件数(デフォルト20、最大100)
cursorstringページネーションカーソル
include_countbooleantrueで total_count を返却
POST/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 }
    ]
  }
}
AIチェックの例
{
  "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 で拒否されます。

GET/v1/monitors/{id}monitors:read

モニター詳細を取得

PATCH/v1/monitors/{id}monitors:write

モニターを更新(シャローマージ、配列は全置換)

DELETE/v1/monitors/{id}monitors:write

モニターを削除(結果も自動削除)

POST/v1/monitors/{id}/executemonitors:execute

手動実行をトリガー(202 Accepted)

POST/v1/monitors/{id}/activatemonitors:write

モニターを有効化

POST/v1/monitors/{id}/deactivatemonitors:write

モニターを無効化

監視結果

GET/v1/monitors/{id}/resultsresults:read

結果一覧を取得

パラメータ説明
statusstringok / changed / error
fromstring開始日時(ISO 8601)
tostring終了日時(ISO 8601)
limitnumber取得件数(デフォルト20、最大100)
cursorstringページネーションカーソル

レスポンスはモニタータイプに応じて異なります:

ビジュアルチェックの結果
{
  "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"
}
GET/v1/monitors/{id}/results/latestresults:read

最新結果を1件取得(レスポンスは上記と同形式)

GET/v1/monitors/{id}/results/{resultId}results:read

結果詳細を取得(レスポンスは上記と同形式)

GET/v1/monitors/{id}/statsresults:read

統計情報を取得

パラメータ説明
periodstring24h / 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
}
スクリーンショットURL・動画URLは署名付きで有効期限1時間です。期限切れ時は同じエンドポイントを再呼び出ししてください。

クロール

GET/v1/crawlscrawls:read

クロールジョブ一覧

POST/v1/crawlscrawls:write

クロールを開始(202 Accepted)

{
  "name": "example.com 構造チェック",
  "url": "https://example.com",
  "config": {
    "max_depth": 3,
    "max_pages": 100,
    "rendering": "javascript"
  }
}
GET/v1/crawls/{id}crawls:read

ジョブ詳細・進捗

GET/v1/crawls/{id}/pagescrawls:read

クロール済みページ一覧

DELETE/v1/crawls/{id}crawls:write

ジョブを削除

通知設定

GET/v1/notificationsnotifications:read

通知設定一覧

POST/v1/notificationsnotifications:write

通知設定を作成

Slack の例
{
  "name": "Slack通知",
  "type": "slack",
  "events": ["visual_changed", "healthcheck_down"],
  "slack_config": {
    "webhook_url": "https://hooks.slack.com/services/xxx/yyy/zzz"
  }
}
PATCH/v1/notifications/{id}notifications:write

通知設定を更新

DELETE/v1/notifications/{id}notifications:write

通知設定を削除

POST/v1/notifications/{id}/testnotifications:write

テスト通知を送信

AIチェック

Pro プラン以上で利用可能。月次クォータ(Pro: 50回 / Enterprise: 500回)を消費します。AIチェック「監視」の CRUD は /v1/monitorstype=ai_check)を使い、ここではジョブ・指摘の取得と単発実行を扱います。

GET/v1/ai-checks/jobsai_checks:read

ジョブ一覧を取得

パラメータ説明
statusstringqueued / running / completed / error
source_monitor_idstring起動元 monitor ID
source_result_idstring連動元の result ID
triggerstringmanual / monitor_event / scheduled
fromstring開始日時(ISO 8601)
tostring終了日時(ISO 8601)
limitnumberデフォルト20、最大100
cursorstringページネーションカーソル
POST/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のみ)/ customcustom_enabled_items 必須)。gemini-2.5-pro は Enterprise のみ。

GET/v1/ai-checks/jobs/{jobId}ai_checks:read

ジョブ詳細(スクショURL等含む)

DELETE/v1/ai-checks/jobs/{jobId}ai_checks:write

ジョブ削除(findings・スクショもカスケード削除)

GET/v1/ai-checks/jobs/{jobId}/findingsai_checks:read

指摘一覧

パラメータ説明
categorystringui_ux / seo / accessibility / security 等
severitystringcritical / warning / info
limitnumberデフォルト100、最大500
cursorstringページネーションカーソル
POST/v1/monitors/{monitorId}/ai-checkai_checks:execute

AIチェック監視の手動実行(10分クールダウン)

スナップショット比較

GET/v1/monitors/{monitorId}/compareresults:read

同一 monitor の任意2件の結果を並べて比較(visual / motion)

パラメータ説明
result_astring古い方の result ID(必須)
result_bstring新しい方の 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
  }
}

メンバー

GET/v1/membersmembers:read

メンバー一覧を取得

パラメータ説明
rolestringowner / editor / viewer でフィルタ
limitnumberデフォルト20、最大100
cursorstringページネーションカーソル
PATCH/v1/members/{memberId}members:write

ロールを変更(editor / viewer)

{ "role": "viewer" }

owner への昇格は不可。最後の owner を降格しようとすると 409 conflict を返します。

DELETE/v1/members/{memberId}members:write

メンバー削除(owner は削除不可)

招待

招待リンクは登録メールアドレスに送信されます。API レスポンスには token は含まれません。

GET/v1/invitationsinvitations:read

招待一覧

パラメータ説明
statusstringpending / accepted / declined / expired / cancelled
limitnumberデフォルト20、最大100
cursorstringページネーションカーソル
POST/v1/invitationsinvitations:write

招待を作成(メール送信)

{
  "email": "newuser@example.com",
  "role": "editor"
}

Free プランは招待不可。1時間に10件までの作成レート制限あり。メール送信に失敗してもドキュメントは作成され、レスポンスに email_sent: falsemessage が含まれます。

GET/v1/invitations/{invitationId}invitations:read

招待詳細

DELETE/v1/invitations/{invitationId}invitations:write

招待を取消(accepted は取消不可)

POST/v1/invitations/{invitationId}/resendinvitations:write

招待メールを再送(前回送信から10分のクールダウン)

テナント情報

GET/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
  }
}

レート制限

制限FreeProEnterprise
APIキー数1310
リクエスト/時3060300
リクエスト/日2005003,000

レスポンスヘッダー X-RateLimit-Remaining で残りリクエスト数を確認できます。 超過時は 429 が返り、X-RateLimit-Reset に再試行可能なUnixタイムスタンプが入ります。

エラーコード

HTTPcode原因と対処
400validation_errorリクエストボディが不正。message を確認してフィールドを修正
400invalid_requestURLがプライベートIPに解決される等。SSRF対策
401unauthorizedAPIキーが無効・期限切れ・未指定。Authorizationヘッダーを確認
403forbiddenスコープ不足。必要なスコープ付きのキーを使用
403plan_limit_exceededプラン上限に到達。不要なリソースを削除するかアップグレード
404not_foundリソースが存在しない。IDを確認
429rate_limit_exceededレート制限超過。X-RateLimit-Reset まで待機
500internal_errorサーバーエラー。しばらく待って再試行

CI/CD連携パターン

デプロイ後にビジュアルチェックを自動実行し、差分が閾値を超えたらパイプラインを失敗させる例です。

GitHub Actions
- 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 '{ ... }'
Idempotency-Keyは24時間有効です。UUIDの使用を推奨します。

ページネーション

一覧エンドポイントはカーソルベースのページネーションを使用します。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"