Sonogo Public API · v1
API リファレンス
外部サイト・LP・自社バックエンドから Sonogo にリードを登録するための JSON API。 全エンドポイントは JSON で、API キー (Bearer token) で認証します。
はじめに
概要
Sonogo の API は Sonogo の全機能 (顧客・資料・閲覧セッション・メール・通知・チーム・Webhook) を JSON でアクセスできる REST API です。外部サイトの問合せフォーム / LP / 自社バックエンド / Zapier 等のいずれからも、同じ API キーで叩けます。
- Base URL
https://sono-5.com- Format
- JSON
- Auth
- API key (Bearer)
- CORS
Allow-Origin: *- Transport
- HTTPS のみ
- Version
- v1
エンドポイント一覧
API キーはサーバ側に保存して使用してください。ブラウザ JavaScript には公開しないこと。 自社サイトの問合せフォームから利用する場合は、自社バックエンドに POST → そこから Sonogo API を叩く構成にします。
はじめに
認証
API キー認証のみ。/settings/api で発行したキー (sk_live_...) を Authorization ヘッダに Bearer token として付けます。
Authorization: Bearer sk_live_abcdef1234567890...はじめに
レート制限
- GET (読み取り系): API キー単位で 120 req/min
- POST/PATCH/PUT/DELETE (書き込み系): API キー単位で 60 req/min
/api/v1/lead-submissions: API キー単位で 60 req/min (個別エンドポイント上書きなし)/api/v1/webhooks/:id/test: API キー単位で 10 req/min (誤発火防止のため低め)- ウィンドウは sliding window (60 秒)。超過時は
429 Too Many Requests+Retry-Afterヘッダを返します
エンドポイント
POST/api/v1/lead-submissions
リード (顧客 + 送信イベント) を登録します。同一 team 内で email が一致する顧客があれば再利用、無ければ新規作成します。送信のたびに lead_submissions に 1 行ずつ append され、顧客タイムラインに表示されます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| source | string 必須 | 'document_download' | 'inquiry' | 'webinar' | 'newsletter' | 'trial' | 'custom' | 'manual' |
| customer.name | string 必須 | 顧客名 (最大 200 文字) |
| customer.email | string 任意 | メアド (重複検出キー) |
| customer.phone | string 任意 | 電話番号 |
| customer.company_name | string 任意 | 会社名 |
| customer.fields | object 任意 | 顧客の拡張フィールド (任意 key-value)。department position address notes 等の既知 key は自動的に日本語ラベル化されます。値は顧客プロフィールに恒久保存され、Slack/メール通知の本文にも含まれます。 |
| payload.subject | string 任意 | 件名 (問合せ等) |
| payload.message | string 任意 | 本文 (問合せ等、最大 10000 文字) |
| payload.document_id | uuid 任意 | 資料 ID (指定時はトラッキングリンクも自動発行) |
| payload.<custom_key> | any 任意 | 送信単位で残したい任意 key を追加できます (例: preferred_schedule)。lead_submissions.payload に保存され、Slack/メール通知の本文にも含まれます。 |
| context.utm_source / utm_medium / utm_campaign / utm_term / utm_content | string 任意 | UTM パラメータ (流入計測用) |
| context.referrer | string 任意 | リファラ |
| context.landing_url | string 任意 | ランディング URL |
| tags | string[] 任意 | タグ名 (最大 20 個)。未存在は自動作成 |
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/lead-submissions \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"source": "inquiry",
"customer": {
"name": "山田太郎",
"email": "yamada@example.com",
"company_name": "株式会社サンプル"
},
"payload": {
"subject": "料金について",
"message": "詳しい料金を知りたいです"
},
"context": {
"utm_source": "google",
"utm_campaign": "spring-2026"
},
"tags": ["問合せ"]
}'レスポンス (201 Created)
{
"customer": {
"id": "uuid",
"name": "山田太郎",
"email": "yamada@example.com",
"company_name": "株式会社サンプル",
"reused": false
},
"submission": {
"id": "uuid",
"source": "inquiry",
"created_at": "2026-05-02T10:30:00Z"
},
"tracking_link": null
}tracking_link は payload.document_id 指定時のみ { id, url, document_id, unique_id } が入ります。
エンドポイント
GET/api/v1/customers
チームに紐付く顧客を一覧取得します。search / tag_id でフィルタ、cursor でページング。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| limit | integer 任意 | 1〜200。デフォルト 50 |
| cursor | string 任意 | 前回レスポンスの next_cursor を渡す |
| search | string 任意 | name / email / company_name の部分一致 |
| tag_id | uuid 任意 | タグでフィルタ |
サンプルリクエスト
curl https://sono-5.com/api/v1/customers?limit=50&search=yamada \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"customers": [{
"id": "9f6c1b58-1234-4abc-9def-000000000001",
"name": "山田太郎",
"email": "yamada@example.com",
"phone": "090-1234-5678",
"company_name": "株式会社サンプル",
"notes": null,
"fields": { "department": "営業" },
"created_at": "2026-05-02T10:30:00Z",
"updated_at": "2026-05-02T10:30:00Z",
"tags": [{ "id": "...", "name": "VIP", "color": "#ef4444" }],
"assignees": [],
"stats": {
"link_count": 3,
"document_count": 2,
"total_views": 8,
"last_viewed_at": "2026-05-20T08:15:00Z",
"email_open_count": 5
}
}],
"next_cursor": "2026-05-02T10:30:00Z|9f6c1b58-1234-4abc-9def-000000000001"
}エンドポイント
POST/api/v1/customers
新規顧客を作成します。email が指定されると team 内で重複チェックされ、既存があれば 409 を返します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| name | string 必須 | 顧客名 (最大 200) |
string 任意 | メアド | |
| phone | string 任意 | 電話番号 |
| company_name | string 任意 | 会社名 |
| notes | string 任意 | メモ (最大 10000) |
| fields | object 任意 | 拡張フィールド (任意 key-value) |
| tag_ids | uuid[] 任意 | タグ ID 配列 (最大 50) |
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/customers \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "山田太郎",
"email": "yamada@example.com",
"company_name": "株式会社サンプル"
}'レスポンス (201 Created)
{
"id": "9f6c1b58-1234-4abc-9def-000000000001",
"name": "山田太郎",
"email": "yamada@example.com",
"phone": "090-1234-5678",
"company_name": "株式会社サンプル",
"notes": null,
"fields": { "department": "営業" },
"created_at": "2026-05-02T10:30:00Z",
"updated_at": "2026-05-02T10:30:00Z",
"tags": [{ "id": "...", "name": "VIP", "color": "#ef4444" }],
"assignees": [],
"stats": {
"link_count": 3,
"document_count": 2,
"total_views": 8,
"last_viewed_at": "2026-05-20T08:15:00Z",
"email_open_count": 5
}
}エンドポイント
GET/api/v1/customers/{id}
顧客 ID で 1 件取得します。タグ・担当者・閲覧統計を含む。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/customers/9f6c1b58-1234-4abc-9def-000000000001 \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "9f6c1b58-1234-4abc-9def-000000000001",
"name": "山田太郎",
"email": "yamada@example.com",
"phone": "090-1234-5678",
"company_name": "株式会社サンプル",
"notes": null,
"fields": { "department": "営業" },
"created_at": "2026-05-02T10:30:00Z",
"updated_at": "2026-05-02T10:30:00Z",
"tags": [{ "id": "...", "name": "VIP", "color": "#ef4444" }],
"assignees": [],
"stats": {
"link_count": 3,
"document_count": 2,
"total_views": 8,
"last_viewed_at": "2026-05-20T08:15:00Z",
"email_open_count": 5
}
}エンドポイント
PATCH/api/v1/customers/{id}
指定したフィールドのみ更新します。omit したフィールドは変更されません。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| name | string 任意 | 顧客名 (最大 200) |
string 任意 | メアド | |
| phone | string 任意 | 電話番号 |
| company_name | string 任意 | 会社名 |
| notes | string 任意 | メモ (最大 10000) |
| fields | object 任意 | 拡張フィールド (任意 key-value) |
サンプルリクエスト
curl -X PATCH https://sono-5.com/api/v1/customers/9f6c1b58-... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "notes": "更新後のメモ" }'レスポンス (201 Created)
{
"id": "9f6c1b58-1234-4abc-9def-000000000001",
"name": "山田太郎",
"email": "yamada@example.com",
"phone": "090-1234-5678",
"company_name": "株式会社サンプル",
"notes": null,
"fields": { "department": "営業" },
"created_at": "2026-05-02T10:30:00Z",
"updated_at": "2026-05-02T10:30:00Z",
"tags": [{ "id": "...", "name": "VIP", "color": "#ef4444" }],
"assignees": [],
"stats": {
"link_count": 3,
"document_count": 2,
"total_views": 8,
"last_viewed_at": "2026-05-20T08:15:00Z",
"email_open_count": 5
}
}エンドポイント
DELETE/api/v1/customers/{id}
顧客を削除します。関連する送信履歴・トラッキングリンクも cascade 削除されます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl -X DELETE https://sono-5.com/api/v1/customers/9f6c1b58-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "id": "9f6c1b58-...", "deleted": true }エンドポイント
GET/api/v1/customers/{id}/timeline
顧客のリード送信・閲覧セッション・メールスレッドを時系列で取得します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/customers/9f6c1b58-.../timeline \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"events": [
{
"type": "viewing_session",
"occurred_at": "2026-05-20T08:00:00Z",
"id": "11111111-...",
"title": "サービス紹介資料 v3 を閲覧",
"summary": "12 / 24 ページ閲覧",
"metadata": { "document_id": "4f8c9b2a-..." }
},
{
"type": "lead_submission",
"occurred_at": "2026-05-02T10:30:00Z",
"id": "...",
"title": "問合せ",
"summary": "料金について",
"metadata": null
}
]
}エンドポイント
GET/api/v1/documents
チームの資料を一覧取得します。search (title 部分一致) / tag_id でフィルタ可。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| limit | integer 任意 | 1〜200。デフォルト 50 |
| cursor | string 任意 | 前回レスポンスの next_cursor を渡す |
| search | string 任意 | title の部分一致 |
| tag_id | uuid 任意 | タグでフィルタ |
サンプルリクエスト
curl https://sono-5.com/api/v1/documents?limit=50 \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"documents": [{
"id": "4f8c9b2a-1234-5678-9abc-def012345678",
"title": "サービス紹介資料 v3",
"description": "営業向け 16:9 スライド",
"original_file_url": "https://.../sonogo-deck.pdf",
"original_file_name": "sonogo-deck.pdf",
"thumbnail_url": "https://.../thumb.png",
"page_count": 24,
"created_at": "2026-05-01T10:00:00Z",
"updated_at": "2026-05-10T09:00:00Z",
"tags": [{ "id": "...", "name": "営業", "color": "#3b82f6" }]
}],
"next_cursor": null
}エンドポイント
POST/api/v1/documents
資料 (PDF) のメタを作成します。ファイル本体は別途 Storage にアップロードして URL を渡してください。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| title | string 必須 | 資料タイトル (最大 200) |
| description | string 任意 | 説明 (最大 10000) |
| original_file_url | string 任意 | 元ファイル URL |
| original_file_name | string 任意 | 元ファイル名 |
| thumbnail_url | string 任意 | サムネイル URL |
| page_count | integer 任意 | ページ数 |
| tag_ids | uuid[] 任意 | タグ ID 配列 (最大 50) |
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/documents \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"title": "サービス紹介資料 v3",
"original_file_url": "https://.../sonogo-deck.pdf",
"page_count": 24
}'レスポンス (201 Created)
{
"id": "4f8c9b2a-1234-5678-9abc-def012345678",
"title": "サービス紹介資料 v3",
"description": "営業向け 16:9 スライド",
"original_file_url": "https://.../sonogo-deck.pdf",
"original_file_name": "sonogo-deck.pdf",
"thumbnail_url": "https://.../thumb.png",
"page_count": 24,
"created_at": "2026-05-01T10:00:00Z",
"updated_at": "2026-05-10T09:00:00Z",
"tags": [{ "id": "...", "name": "営業", "color": "#3b82f6" }]
}エンドポイント
GET/api/v1/documents/{id}
資料を 1 件取得します。versions (ファイル差し替え履歴) を含みます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/documents/4f8c9b2a-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "4f8c9b2a-1234-5678-9abc-def012345678",
"title": "サービス紹介資料 v3",
"description": "営業向け 16:9 スライド",
"original_file_url": "https://.../sonogo-deck.pdf",
"original_file_name": "sonogo-deck.pdf",
"thumbnail_url": "https://.../thumb.png",
"page_count": 24,
"created_at": "2026-05-01T10:00:00Z",
"updated_at": "2026-05-10T09:00:00Z",
"tags": [{ "id": "...", "name": "営業", "color": "#3b82f6" }]
,
"versions": [
{
"id": "33333333-...",
"document_id": "4f8c9b2a-...",
"version_number": 1,
"original_file_url": "https://.../v1.pdf",
"original_file_name": "sonogo-deck.pdf",
"thumbnail_url": null,
"page_count": 24,
"created_at": "2026-05-01T10:00:00Z"
}
]
}エンドポイント
PATCH/api/v1/documents/{id}
資料のメタ情報を更新します。omit したフィールドは変更されません。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| title | string 任意 | 資料タイトル (最大 200) |
| description | string 任意 | 説明 (最大 10000) |
| original_file_url | string 任意 | 元ファイル URL |
| original_file_name | string 任意 | 元ファイル名 |
| thumbnail_url | string 任意 | サムネイル URL |
| page_count | integer 任意 | ページ数 |
サンプルリクエスト
curl -X PATCH https://sono-5.com/api/v1/documents/4f8c9b2a-... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "title": "サービス紹介資料 v4" }'レスポンス (201 Created)
{
"id": "4f8c9b2a-1234-5678-9abc-def012345678",
"title": "サービス紹介資料 v3",
"description": "営業向け 16:9 スライド",
"original_file_url": "https://.../sonogo-deck.pdf",
"original_file_name": "sonogo-deck.pdf",
"thumbnail_url": "https://.../thumb.png",
"page_count": 24,
"created_at": "2026-05-01T10:00:00Z",
"updated_at": "2026-05-10T09:00:00Z",
"tags": [{ "id": "...", "name": "営業", "color": "#3b82f6" }]
}エンドポイント
DELETE/api/v1/documents/{id}
資料を削除します。トラッキングリンク・閲覧履歴も cascade 削除されます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl -X DELETE https://sono-5.com/api/v1/documents/4f8c9b2a-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "id": "4f8c9b2a-...", "deleted": true }エンドポイント
GET/api/v1/documents/{id}/versions
資料のファイル差し替え履歴を取得します (version_number 降順)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/documents/4f8c9b2a-.../versions \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"versions": [
{
"id": "33333333-...",
"document_id": "4f8c9b2a-...",
"version_number": 2,
"original_file_url": "https://.../v2.pdf",
"original_file_name": "sonogo-deck-v2.pdf",
"thumbnail_url": null,
"page_count": 26,
"created_at": "2026-05-10T09:00:00Z"
}
]
}エンドポイント
GET/api/v1/sessions
viewer での資料閲覧セッションを一覧取得します。デフォルトでメンバー閲覧 (is_member_access = true) は除外。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| limit | integer 任意 | 1〜200。デフォルト 50 |
| cursor | string 任意 | 前回レスポンスの next_cursor を渡す |
| customer_id | uuid 任意 | 顧客でフィルタ |
| document_id | uuid 任意 | 資料でフィルタ |
| since | datetime 任意 | ISO 8601。この日時以降の started_at |
| until | datetime 任意 | ISO 8601。この日時以前の started_at |
| include_member_views | boolean 任意 | メンバー閲覧 (内部 IP) を含めるか。デフォルト false |
サンプルリクエスト
curl https://sono-5.com/api/v1/sessions?limit=50&document_id=4f8c9b2a-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"sessions": [{
"id": "11111111-1111-4111-8111-111111111111",
"tracking_link_id": "22222222-...",
"document_id": "4f8c9b2a-...",
"file_version_id": "33333333-...",
"customer_id": "9f6c1b58-...",
"started_at": "2026-05-20T08:00:00Z",
"ended_at": "2026-05-20T08:09:30Z",
"duration_seconds": 570,
"inactive_seconds": 0,
"is_active": false,
"is_member_access": false,
"pages_viewed": 12,
"total_pages": 24,
"completion_rate": 0.5,
"end_reason": "tab_closed",
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 ...",
"device_type": "desktop",
"browser_name": "Chrome",
"os_name": "macOS",
"geo_country": "JP",
"geo_region": "Tokyo",
"geo_city": "Shibuya",
"access_quality": "normal",
"referrer": null
}],
"next_cursor": null
}エンドポイント
GET/api/v1/sessions/{id}
セッション 1 件を取得します。page_dwell_times (ページ別滞在時間) を含みます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/sessions/11111111-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "11111111-1111-4111-8111-111111111111",
"tracking_link_id": "22222222-...",
"document_id": "4f8c9b2a-...",
"file_version_id": "33333333-...",
"customer_id": "9f6c1b58-...",
"started_at": "2026-05-20T08:00:00Z",
"ended_at": "2026-05-20T08:09:30Z",
"duration_seconds": 570,
"inactive_seconds": 0,
"is_active": false,
"is_member_access": false,
"pages_viewed": 12,
"total_pages": 24,
"completion_rate": 0.5,
"end_reason": "tab_closed",
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 ...",
"device_type": "desktop",
"browser_name": "Chrome",
"os_name": "macOS",
"geo_country": "JP",
"geo_region": "Tokyo",
"geo_city": "Shibuya",
"access_quality": "normal",
"referrer": null
,
"page_dwell_times": [
{ "page_number": 1, "dwell_time_ms": 8200, "enter_count": 1, "file_version_id": "33333333-..." },
{ "page_number": 2, "dwell_time_ms": 14500, "enter_count": 1, "file_version_id": "33333333-..." }
]
}エンドポイント
GET/api/v1/email-accounts
チームで接続されている IMAP/SMTP メールアカウントを取得します (パスワード等の暗号化フィールドは含まれません)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/email-accounts \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"accounts": [
{
"id": "...",
"user_id": "...",
"team_id": "...",
"organization_id": "...",
"label": "営業 1 課",
"email_address": "sales@example.com",
"imap_host": "imap.example.com",
"imap_port": 993,
"imap_user": "sales@example.com",
"imap_secure": true,
"smtp_host": "smtp.example.com",
"smtp_port": 587,
"smtp_user": "sales@example.com",
"smtp_secure": true,
"sync_folders": ["INBOX", "Sent"],
"visibility": "team",
"is_active": true,
"last_sync_at": "2026-05-20T08:00:00Z",
"last_sync_error": null,
"created_at": "2026-05-01T00:00:00Z",
"updated_at": "2026-05-20T08:00:00Z"
}
]
}エンドポイント
GET/api/v1/email-threads
個別メール (IMAP/SMTP) のスレッドを一覧取得します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| limit | integer 任意 | 1〜200。デフォルト 50 |
| cursor | string 任意 | 前回レスポンスの next_cursor を渡す |
| account_id | uuid 任意 | メールアカウントでフィルタ |
| customer_id | uuid 任意 | 顧客でフィルタ |
| is_read | boolean 任意 | 未読/既読フィルタ |
サンプルリクエスト
curl https://sono-5.com/api/v1/email-threads?limit=50&customer_id=9f6c1b58-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"threads": [
{
"id": "...",
"account_id": "...",
"customer_id": "9f6c1b58-...",
"subject": "Re: 料金について",
"snippet": "ご返信ありがとうございます...",
"message_count": 4,
"is_read": false,
"is_starred": false,
"has_sonogo_message": true,
"last_message_at": "2026-05-20T09:00:00Z",
"created_at": "2026-05-02T10:30:00Z",
"updated_at": "2026-05-20T09:00:00Z"
}
],
"next_cursor": null
}エンドポイント
GET/api/v1/email-threads/{id}
スレッド 1 件と、そのスレッドに含まれる全メッセージを取得します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/email-threads/aaaa-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "...",
"subject": "Re: 料金について",
"snippet": "...",
"message_count": 4,
"is_read": true,
"messages": [
{
"id": "...",
"thread_id": "...",
"direction": "inbound",
"from_address": "yamada@example.com",
"subject": "料金について",
"body_text": "詳しい料金を知りたいです",
"is_read": true,
"received_at": "2026-05-02T10:30:00Z"
}
]
}省略されているフィールドあり。実際のレスポンスは EmailThread + messages: EmailMessage[] の全フィールドを含みます。
エンドポイント
GET/api/v1/email-messages/{id}
メール 1 件を取得します (body_text / body_html を含む)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/email-messages/bbbb-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "...",
"thread_id": "...",
"account_id": "...",
"direction": "inbound",
"folder": "INBOX",
"from_address": "yamada@example.com",
"from_name": "山田太郎",
"to_addresses": ["sales@example.com"],
"cc_addresses": [],
"bcc_addresses": [],
"subject": "料金について",
"body_text": "詳しい料金を知りたいです",
"body_html": "<p>詳しい料金を知りたいです</p>",
"is_read": true,
"has_tracking_pixel": false,
"send_status": "received",
"received_at": "2026-05-02T10:30:00Z",
"created_at": "2026-05-02T10:30:00Z",
"updated_at": "2026-05-02T10:30:00Z"
}エンドポイント
PATCH/api/v1/email-messages/{id}
メールの既読フラグを切り替えます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| is_read | boolean 任意 | 既読/未読を切り替え |
サンプルリクエスト
curl -X PATCH https://sono-5.com/api/v1/email-messages/bbbb-... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "is_read": true }'レスポンス (201 Created)
{ "id": "bbbb-...", "is_read": true }エンドポイント
GET/api/v1/notifications
ログインユーザー宛の通知を取得します (API キー作成者のユーザー宛)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| limit | integer 任意 | 1〜200。デフォルト 50 |
| cursor | string 任意 | 前回レスポンスの next_cursor を渡す |
| is_read | boolean 任意 | 未読/既読フィルタ |
| type | string 任意 | 通知種別 (opened / viewing / completed / email_opened / lead_created など) |
サンプルリクエスト
curl https://sono-5.com/api/v1/notifications?is_read=false&limit=50 \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"notifications": [{
"id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"type": "viewing",
"title": "山田太郎さんが「サービス紹介資料 v3」を閲覧中",
"body": "12 / 24 ページまで閲覧",
"is_read": false,
"customer_id": "9f6c1b58-...",
"document_id": "4f8c9b2a-...",
"email_id": null,
"email_message_id": null,
"session_id": "11111111-...",
"tracking_link_id": "22222222-...",
"created_at": "2026-05-20T08:02:00Z"
}],
"next_cursor": null
}エンドポイント
GET/api/v1/notifications/unread-count
未読通知の件数を返します (バッジ用)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/notifications/unread-count \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "count": 5 }エンドポイント
PATCH/api/v1/notifications/{id}
通知の既読フラグを切り替えます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| is_read | boolean 必須 | true で既読化、false で未読化 |
サンプルリクエスト
curl -X PATCH https://sono-5.com/api/v1/notifications/aaaa-... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "is_read": true }'レスポンス (201 Created)
{ "id": "aaaaaaaa-...", "is_read": true }エンドポイント
POST/api/v1/notifications/mark-all-read
ログインユーザー宛のすべての未読通知を既読化します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/notifications/mark-all-read \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "updated": 5 }エンドポイント
GET/api/v1/team
API キーに紐付くチーム (teams テーブル 1 行) を返します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/team \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "...",
"organization_id": "...",
"name": "営業部",
"icon_url": null,
"created_at": "2026-04-01T00:00:00Z",
"updated_at": "2026-05-01T00:00:00Z"
}エンドポイント
GET/api/v1/team/members
チームに所属するメンバーを取得します。permissions に org_admin / billing_admin enum 配列。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/team/members \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"members": [
{
"id": "...",
"user_id": "...",
"team_id": "...",
"joined_at": "2026-04-01T00:00:00Z",
"role": "member",
"permissions": ["org_admin"],
"profile": {
"id": "...",
"email": "admin@example.com",
"full_name": "管理者太郎",
"avatar_url": null
}
}
]
}エンドポイント
GET/api/v1/team/invites
発行済みのチーム招待 (招待リンク + 期限) を取得します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/team/invites \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"invites": [
{
"id": "...",
"team_id": "...",
"email": "new@example.com",
"role": "member",
"grant_permissions": [],
"invited_by": "...",
"token": "...",
"expires_at": "2026-06-05T00:00:00Z",
"accepted_at": null,
"created_at": "2026-05-05T00:00:00Z"
}
]
}エンドポイント
POST/api/v1/team/invites
新しい招待を発行します (招待メール自動送信は別系統)。同じ email で有効な招待が既存だと 409 を返します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
string 必須 | 招待先メアド | |
| grant_permissions | string[] 任意 | org_admin / billing_admin の配列 (最大 2)。省略時は通常メンバー |
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/team/invites \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"email": "new@example.com",
"grant_permissions": ["billing_admin"]
}'レスポンス (201 Created)
{
"id": "...",
"team_id": "...",
"email": "new@example.com",
"role": "member",
"grant_permissions": ["billing_admin"],
"invited_by": "...",
"token": "uuid-token-...",
"expires_at": "2026-06-05T00:00:00Z",
"accepted_at": null,
"created_at": "2026-05-05T00:00:00Z"
}エンドポイント
DELETE/api/v1/team/invites/{token}
未受諾の招待を取り消します。token は招待発行時のレスポンスに含まれます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl -X DELETE https://sono-5.com/api/v1/team/invites/uuid-token-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "token": "uuid-token-...", "deleted": true }エンドポイント
GET/api/v1/webhooks
チームに登録されている Webhook を取得します (secret は返しません)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/webhooks \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "webhooks": [{
"id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
"team_id": "...",
"organization_id": "...",
"name": "Slack 通知",
"url": "https://hooks.slack.com/services/T.../B.../...",
"event_types": ["lead_created", "viewing"],
"is_active": true,
"last_status": 200,
"last_error": null,
"last_fired_at": "2026-05-20T08:00:00Z",
"created_at": "2026-05-01T00:00:00Z",
"updated_at": "2026-05-20T08:00:00Z"
}] }エンドポイント
POST/api/v1/webhooks
新しい Webhook を登録します。URL は SSRF 対策のためプライベート IP / 内部ホストは拒否されます。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| name | string 必須 | Webhook 名 (最大 200) |
| url | string 必須 | 通知先 URL (https://...)。Discord / Slack / Teams / Google Chat / 汎用エンドポイントを自動判別 |
| event_types | string[] 必須 | 購読するイベント名の配列 (例: lead_created, viewing, email_opened) |
| secret | string 任意 | 署名検証用シークレット (最大 500)。指定時は X-Sonogo-Signature ヘッダを付与 |
| is_active | boolean 任意 | デフォルト true |
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/webhooks \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Slack 通知",
"url": "https://hooks.slack.com/services/T.../B.../...",
"event_types": ["lead_created", "viewing"]
}'レスポンス (201 Created)
{
"id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
"team_id": "...",
"organization_id": "...",
"name": "Slack 通知",
"url": "https://hooks.slack.com/services/T.../B.../...",
"event_types": ["lead_created", "viewing"],
"is_active": true,
"last_status": 200,
"last_error": null,
"last_fired_at": "2026-05-20T08:00:00Z",
"created_at": "2026-05-01T00:00:00Z",
"updated_at": "2026-05-20T08:00:00Z"
}エンドポイント
GET/api/v1/webhooks/{id}
Webhook 1 件を取得します (secret は返しません)。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl https://sono-5.com/api/v1/webhooks/bbbb-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{
"id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
"team_id": "...",
"organization_id": "...",
"name": "Slack 通知",
"url": "https://hooks.slack.com/services/T.../B.../...",
"event_types": ["lead_created", "viewing"],
"is_active": true,
"last_status": 200,
"last_error": null,
"last_fired_at": "2026-05-20T08:00:00Z",
"created_at": "2026-05-01T00:00:00Z",
"updated_at": "2026-05-20T08:00:00Z"
}エンドポイント
PATCH/api/v1/webhooks/{id}
Webhook の設定を部分更新します。secret を null にすると署名検証なしに戻ります。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|---|---|
| name | string 任意 | Webhook 名 (最大 200) |
| url | string 任意 | 通知先 URL (https://...)。Discord / Slack / Teams / Google Chat / 汎用エンドポイントを自動判別 |
| event_types | string[] 任意 | 購読するイベント名の配列 (例: lead_created, viewing, email_opened) |
| secret | string 任意 | 署名検証用シークレット (最大 500)。指定時は X-Sonogo-Signature ヘッダを付与 |
| is_active | boolean 任意 | デフォルト true |
サンプルリクエスト
curl -X PATCH https://sono-5.com/api/v1/webhooks/bbbb-... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'レスポンス (201 Created)
{
"id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
"team_id": "...",
"organization_id": "...",
"name": "Slack 通知",
"url": "https://hooks.slack.com/services/T.../B.../...",
"event_types": ["lead_created", "viewing"],
"is_active": true,
"last_status": 200,
"last_error": null,
"last_fired_at": "2026-05-20T08:00:00Z",
"created_at": "2026-05-01T00:00:00Z",
"updated_at": "2026-05-20T08:00:00Z"
}エンドポイント
DELETE/api/v1/webhooks/{id}
Webhook を削除します。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl -X DELETE https://sono-5.com/api/v1/webhooks/bbbb-... \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "id": "bbbb-...", "deleted": true }エンドポイント
POST/api/v1/webhooks/{id}/test
テストイベント ([TEST] テスト通知) を Webhook に送信します。誤発火防止のため 10 req/min に制限されています。
リクエストボディ
| Field | Type / 必須 | 説明 |
|---|
サンプルリクエスト
curl -X POST https://sono-5.com/api/v1/webhooks/bbbb-.../test \
-H "Authorization: Bearer sk_live_..."レスポンス (201 Created)
{ "ok": true, "status": 200, "error": null, "kind": "slack" }Webhook
Webhook 通知 (outbound)
イベント発生時に Sonogo から外部 URL へ POST します。/settings/notifications の「Webhook 連携」で URL とイベント種別を登録してください。 Discord・Microsoft Teams・Google Chat の URL は自動でそれぞれのリッチメッセージ形式に整形されます。
サポート対象イベント
| Event | 説明 |
|---|---|
| lead_created | リード作成 (API・フォーム経由含む) |
| viewing | 資料閲覧開始 |
| completed | 資料完読 |
| email_opened | メルマガ開封 |
| email_clicked | メルマガ内リンククリック |
| email_bounced | メルマガ配信失敗 |
| email_unsubscribed | メルマガ配信停止 |
| email_complained | メルマガ迷惑メール報告 |
| email_replied | 個別メール返信 |
| imap_opened | 個別メール開封 |
| imap_clicked | 個別メール内リンククリック |
| imap_watched_sender | 監視リストに登録した送信者から個別メール受信 |
| imap_scheduled_sent | 予約していた個別メールの送信が完了 |
| imap_scheduled_failed | 予約していた個別メールの送信が失敗 |
ペイロード形式
POST <your-webhook-url>
Content-Type: application/json
User-Agent: Sonogo-Webhook/1.0
X-Sonogo-Signature: sha256=<hex> (汎用 webhook で secret 設定時のみ)
{
"event": "lead_created",
"occurred_at": "2026-05-02T10:30:00Z",
"team_id": "uuid",
"organization_id": "uuid",
"data": {
"title": "山田太郎 さんからお問い合わせがありました",
"body": "株式会社サンプル / yamada@example.com",
"action_url": "https://sono-5.com/customers?customerId=<id>&drawer=timeline",
"customer": {
"id": "uuid",
"name": "山田太郎",
"email": "yamada@example.com",
"phone": "090-0000-0000",
"company_name": "株式会社サンプル"
},
"assignee": "営業 花子",
"document_id": null,
"email_id": null,
"email_message_id": null
}
}署名検証
シークレットを設定した場合、ペイロード本文の HMAC SHA256 が X-Sonogo-Signature に入ります。 受信側で同じシークレットで再計算して一致するか確認してください。
import crypto from "crypto"
function verifySignature(rawBody, header, secret) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(rawBody).digest("hex")
return crypto.timingSafeEqual(
Buffer.from(header),
Buffer.from(expected),
)
}配信ポリシー
- Discord / Microsoft Teams / Google Chat の URL は自動判別: それぞれのリッチメッセージ形式に整形して送信される (汎用 JSON ではない)
- 汎用 JSON: 上記以外の URL (Zapier / Make / n8n / 自前サーバー) には上記の
event/data構造で POST - fire-and-forget: Sonogo はレスポンス本文を読まない。5 秒タイムアウト
- リトライなし: 失敗時は
last_status/last_errorに記録されるだけ (Sonogo 側の運用観測のみ) - 順序保証なし: 同一 customer の複数イベントが順不同で届きうる
- 冪等性: 受信側で
event+occurred_at+customer.id等の組合せでデデュプ推奨 - 3xx リダイレクト禁止: Sonogo 側で reject される
- localhost / プライベート IP 禁止: SSRF 対策で reject される。Public な URL を登録すること
- Slack URL は登録不可:
hooks.slack.com/...は弾かれる。Slack 連携は OAuth (ワンクリック接続) を使うこと
エラー
エラー仕様
エラー時は HTTP ステータスと JSON ボディを返します。
{
"error": "Validation error",
"details": {
"customer.email": [
"Invalid email"
]
}
}主なステータスコード
| Status | 意味 |
|---|---|
| 400 | リクエスト不正 (JSON パース失敗 / バリデーションエラー) |
| 401 | API キー無効 / 失効 |
| 403 | クォータ超過 (link quota など) |
| 404 | フォーム / 資料 / 対象リソース未発見 |
| 410 | フォームが無効化済み (アーカイブ等) |
| 429 | レート制限超過 (Retry-After ヘッダ参照) |
| 500 | サーバ内部エラー (重複時はサポートにご連絡ください) |
この情報は OpenAPI YAML / Markdown / Claude Skill としても /docs からダウンロードできます。