> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tiro.ooo/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook の概要

> Webhookエンドポイントは、ノート・要約・ドキュメントが変わった瞬間にTiroがHTTP POSTを送る、あなたのアプリのURLです。ポーリングなしでイベントをリアルタイムに受け取れます。

export const EventBaseStructure = {
  id: "evt_01J9ABCDEF",
  type: "note.created",
  createdAt: "2025-09-05T07:12:34Z",
  workspaceGuid: "ws_a1b2c3d4",
  data: {
    resourceType: "Note",
    resourceId: "note-guid-123",
    resource: {
      "title": "Meeting Note"
    }
  }
};

export const Json = ({data, lang = 'json', spaces = 2}) => <pre>
    <code className={`language-${lang}`}>{JSON.stringify(data, null, spaces)}</code>
  </pre>;

## Webhookエンドポイントとは？

Webhookエンドポイント（endpoint）は、ノート・要約・ドキュメントが変わった瞬間に Tiro が HTTP POST リクエストを送信する、お客様のアプリケーションの URL です。[Tiro Platform](https://platform.tiro.ooo)にエンドポイントを一度登録しておくと、Tiro がすべてのイベントをリアルタイムでその宛先へ送信します。API をポーリングする必要はありません。

## Webhook とは

Webhook を利用しますと、ワークスペースでイベントが発生した際に、アプリケーションがリアルタイムで通知を受け取れます。API をポーリングする代わりに、何かが起こるたびに Tiro がお客様の endpoint へ HTTP POST リクエストを送信します。

## Webhook の仕組み

1. **設定する**: アプリケーションに webhook の endpoint を用意します
2. **登録する**: 受け取りたいイベントを処理するために、endpoint を追加します
3. **受信する**: イベントが発生すると即座に通知が届きます
4. **処理する**: アプリケーションでイベントのデータを処理します

## イベントとリソースの構造

Webhook は **イベント（Events）** と **リソース（Resources）** を中心に構成されています。

### イベント

イベントは、ワークスペースで発生したアクションを表します。詳しくは [Note Events](/ja/developers/webhooks/events/note-events)、[Note Document Events](/ja/developers/webhooks/events/note-document-events)、[Note Summary Events](/ja/developers/webhooks/events/note-summary-events)、[FolderNote Events](/ja/developers/webhooks/events/folder-note-events) をご覧ください。
Webhook イベントは metadata のみを含めることで、サイズが数百 KB 未満に収まるよう設計されています。transcript や script などの大きなコンテンツは、webhook の信頼性とパフォーマンスを確保するため、別の API を通じてアクセスします。

### リソース

リソースは、イベントの対象となる主要なエンティティを表します。現在サポートしているのは以下のとおりです。

* `Note`: 個々のノートのリソース
* `NoteDocument`: ノートから生成されるテンプレートベースのドキュメント
* `NoteSummary`: ノートに対して AI が生成する要約
* `FolderNoteRelation`: フォルダとノートの関係

## Webhook の payload 構造

すべての webhook イベントは、標準の [Event Structure](/ja/developers/webhooks/events/schema) 構造に従います。

<Json data={EventBaseStructure} />

## セキュリティ

Webhook リクエストは、Authorization ヘッダーに設定された secret key で認証されます。

```
Authorization: Bearer {secret_key}
```

secret key は webhook の endpoint を設定する際に発行され、受信するリクエストの真正性を検証するために使用します。設定済みの secret と受信した secret を比較するだけで、真正性を確認できます。

### 検証の例

<CodeGroup>
  ```javascript Node.js theme={"system"}
  function verifyWebhookAuth(authHeader, expectedSecret) {
    const token = authHeader.replace('Bearer ', '');
    return token === expectedSecret;
  }

  // Usage in your webhook endpoint
  app.post('/ja/developers/webhooks/tiro', (req, res) => {
    const authHeader = req.headers.authorization;
    
    if (!verifyWebhookAuth(authHeader, process.env.WEBHOOK_SECRET)) {
      return res.status(401).send('Unauthorized');
    }
    
    // Process webhook event
    const event = req.body;
    handleWebhookEvent(event);
    
    res.status(200).send('OK');
  });
  ```

  ```python Python theme={"system"}
  import os
  from flask import Flask, request

  def verify_webhook_auth(auth_header, expected_secret):
      if not auth_header or not auth_header.startswith('Bearer '):
          return False
      token = auth_header.replace('Bearer ', '')
      return token == expected_secret

  # Usage in your webhook endpoint
  @app.route('/ja/developers/webhooks/tiro', methods=['POST'])
  def handle_webhook():
      auth_header = request.headers.get('Authorization')
      
      if not verify_webhook_auth(auth_header, os.getenv('WEBHOOK_SECRET')):
          return 'Unauthorized', 401
      
      # Process webhook event
      event = request.get_json()
      handle_webhook_event(event)
      
      return 'OK', 200
  ```

  ```go Go theme={"system"}
  import (
      "encoding/json"
      "net/http"
      "os"
      "strings"
  )

  func verifyWebhookAuth(authHeader, expectedSecret string) bool {
      if !strings.HasPrefix(authHeader, "Bearer ") {
          return false
      }
      token := strings.TrimPrefix(authHeader, "Bearer ")
      return token == expectedSecret
  }

  // Usage in your webhook endpoint
  func handleWebhook(w http.ResponseWriter, r *http.Request) {
      authHeader := r.Header.Get("Authorization")
      
      if !verifyWebhookAuth(authHeader, os.Getenv("WEBHOOK_SECRET")) {
          http.Error(w, "Unauthorized", http.StatusUnauthorized)
          return
      }
      
      // Process webhook event
      var event WebhookEvent
      json.NewDecoder(r.Body).Decode(&event)
      handleWebhookEvent(event)
      
      w.WriteHeader(http.StatusOK)
  }
  ```

  ```kotlin Kotlin + Spring theme={"system"}
  @RestController
  class WebhookController {
      
      @Value("\${webhook.secret}")
      private lateinit var webhookSecret: String
      
      private fun verifyWebhookAuth(authHeader: String?, expectedSecret: String): Boolean {
          if (authHeader?.startsWith("Bearer ") != true) {
              return false
          }
          val token = authHeader.removePrefix("Bearer ")
          return token == expectedSecret
      }
      
      // Usage in your webhook endpoint
      @PostMapping("/ja/developers/webhooks/tiro")
      fun handleWebhook(
          @RequestHeader("Authorization") authHeader: String?,
          @RequestBody event: WebhookEvent
      ): ResponseEntity<String> {
          if (!verifyWebhookAuth(authHeader, webhookSecret)) {
              return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized")
          }
          
          // Process webhook event
          handleWebhookEvent(event)
          return ResponseEntity.ok("OK")
      }
  }
  ```
</CodeGroup>

## 配信とリトライ

* **Method**: HTTP POST
* **Content-Type**: `application/json`
* **Timeout**: 60 秒
* **Retries**: 最大 5 回のリトライ（合計 6 回の試行）。exponential backoff で実施します
* **Success**: 2xx の HTTP ステータスコードであれば成功とみなします

### リトライのスケジュール

1. 15 秒後
2. 30 秒後
3. 5 分後
4. 30 分後
5. 2 時間後

## はじめに

1. **endpoint を用意する**: POST リクエストを受信できる HTTP の endpoint を作成します
2. **webhook を設定する**: [Tiro Platform](https://platform.tiro.ooo) で webhook の endpoint を登録します
3. **イベントを処理する**: アプリケーションで受信した webhook の payload を処理します

webhook の endpoint は [Tiro Platform](https://platform.tiro.ooo) で設定できます。

<Note>
  Webhook の endpoint はワークスペース単位で登録・管理されます。Platform で endpoint を追加すると、現在のワークスペースのイベントがその endpoint に配信されます。複数のワークスペースを運用する場合は、ワークスペースごとに endpoint を登録し、payload 最上位の `workspaceGuid` でイベントの送信元ワークスペースを判別してください。
</Note>

endpoint を登録したら、受信する [Event Structure](/ja/developers/webhooks/events/schema) を把握しましょう。そのうえで、本番運用を始める前に [Best Practices](/ja/developers/webhooks/best-practices) を読み、リトライ・冪等性・署名検証への対応をご確認ください。
