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

# 이벤트

> 웹훅 본문의 필드와 이벤트 17개, 이벤트별 data 형식을 정리합니다.

## 요청 형식

```http theme={null}
POST /your/webhook HTTP/1.1
Content-Type: application/json
User-Agent: bottari-integration/1.0
x-bottari-signature: sha256=...
```

```json theme={null}
{
  "id": "44444444-4444-4444-8444-444444444444",
  "timestamp": "2026-01-15T02:30:12.345Z",
  "workspace_id": "exampleTeam1",
  "workspace_name": "예시 팀",
  "subscription_id": "exampleSub01",
  "integration_id": "exampleInt01",
  "authors": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "type": "person"
    }
  ],
  "attempt_number": 1,
  "api_version": "2026-03-11",
  "entity": {
    "id": "exampleRow01",
    "type": "page"
  },
  "type": "page.properties_updated",
  "data": {
    "parent": {
      "id": "exampleDb001",
      "type": "database",
      "data_source_id": "exampleDb001"
    },
    "updated_properties": [
      "title",
      "exampleFld01"
    ]
  }
}
```

* `id`: 이벤트 ID입니다. 재시도 때도 같습니다. 중복을 거를 때 사용하세요.
* `timestamp`: 합쳐진 변경 중 첫 변경의 시각입니다.
* `workspace_id` · `workspace_name`: 팀 ID와 팀 이름입니다.
* `subscription_id` · `integration_id`: 구독 ID와 연동 ID입니다.
* `authors`: 변경한 주체입니다. [작성자 자세히 알아보기 →](#작성자)
* `attempt_number`: 몇 번째 시도인지 나타냅니다. 1부터 시작합니다.
* `api_version`: 항상 `2026-03-11`입니다.
* `entity`: 바뀐 대상입니다. `type`은 `page` · `database` · `data_source` · `comment`입니다.
* `type`: 이벤트 이름입니다.
* `data`: 이벤트마다 다릅니다.

## 이벤트 목록

구독에서 고를 수 있는 이벤트는 페이지 8개 · 데이터베이스 4개 · 데이터 소스 2개 · 댓글 3개로 모두 17개입니다. [이벤트 묶기 자세히 알아보기 →](https://developers.bottari.ai/ko/webhooks/batching.md)

### 페이지

행과 하위 문서의 이벤트입니다.

| 이벤트 | 발생 시점 | `data` | 전송 시점 |
| - | - | - | - |
| `page.created` | 행이나 하위 문서를 만들었습니다. | `parent` | 60초 묶기 |
| `page.properties_updated` | 속성 값이나 제목을 바꿨습니다. | `parent` · `updated_properties` | 60초 묶기 |
| `page.content_updated` | 본문을 바꿨습니다. 하위 문서 제목을 바꾸거나 인라인 데이터베이스를 넣고 빼도 부모 문서에 전송합니다. | `parent` · `updated_blocks` | 60초 묶기 |
| `page.moved` | 다른 곳으로 옮겼습니다. | `parent`(새 부모) | 60초 묶기 |
| `page.deleted` | 휴지통에 넣었습니다. | `parent` | 60초 묶기 |
| `page.undeleted` | 휴지통에서 되살렸습니다. | `parent` | 60초 묶기 |
| `page.locked` | 잠갔습니다. | `parent` | 바로 |
| `page.unlocked` | 잠금을 풀었습니다. | `parent` | 바로 |

행을 다른 데이터베이스로 옮기면 `page.moved`(`parent`는 새 데이터베이스)와 이전 데이터베이스의 `data_source.content_updated`를 함께 전송합니다.

### 데이터베이스

| 이벤트 | 발생 시점 | `data` | 전송 시점 |
| - | - | - | - |
| `database.created` | 연결된 문서 안에 인라인 데이터베이스를 만들었습니다. | `parent` | 60초 묶기 |
| `database.moved` | 인라인 데이터베이스를 다른 문서로 옮겼습니다. | `parent`(새 문서) | 60초 묶기 |
| `database.deleted` | 휴지통에 넣었습니다. | `parent` | 60초 묶기 |
| `database.undeleted` | 휴지통에서 되살렸습니다. | `parent` | 60초 묶기 |

인라인 데이터베이스 이벤트를 전송할 때 부모 문서의 `page.content_updated`도 함께 전송합니다. 다른 문서로 옮기면 양쪽 문서에 모두 전송합니다. 인라인 데이터베이스가 들어 있는 문서를 지우면 그 문서의 `page.deleted`만 전송합니다.

### 데이터 소스

| 이벤트 | 발생 시점 | `data` | 전송 시점 |
| - | - | - | - |
| `data_source.schema_updated` | 속성을 만들거나 고치거나 지웠습니다. 선택지를 바꿔도 전송합니다. | `parent` · `updated_properties` | 60초 묶기 |
| `data_source.content_updated` | 행이 그 데이터베이스에서 빠졌습니다. | `parent` · `updated_blocks` | 바로 |

`data_source.created` · `moved` · `deleted` · `undeleted`는 없습니다. Bottari 데이터베이스에는 데이터 소스가 하나여서 따로 발생하지 않습니다.

### 댓글

`댓글 읽기` 권한이 꺼져 있으면 전송하지 않습니다.

| 이벤트 | 발생 시점 | `data` | 전송 시점 |
| - | - | - | - |
| `comment.created` | 댓글이나 답글을 달았습니다. | `discussion_id` · `page_id` · `parent` | 바로 |
| `comment.updated` | 댓글을 고쳤습니다. 다시 읽으면 고친 내용과 바뀐 `last_edited_time`을 반환합니다. | `discussion_id` · `page_id` · `parent` | 바로 |
| `comment.deleted` | 댓글을 지웠습니다. 답글이 달린 스레드를 지우면 지워지는 댓글마다 하나씩 전송합니다. | `discussion_id` · `page_id` · `parent` | 바로 |

## data 필드

### parent

대상에 따라 형식이 다릅니다. API 객체의 `parent`와 달리 `type`에 `database` · `page` · `space` · `block`이 들어갑니다.

| 대상 | `parent` |
| - | - |
| 행 | `{ "id": "<데이터베이스>", "type": "database", "data_source_id": "<데이터베이스>" }` |
| 하위 문서 | `{ "id": "<부모 문서>", "type": "page" }` |
| 인라인 데이터베이스 | `{ "id": "<그 문서>", "type": "page" }` |
| 최상위 데이터베이스 | `{ "id": "<팀>", "type": "space" }` |
| 데이터 소스 | `{ "id": "<데이터베이스>", "type": "database" }` |
| 페이지에 단 댓글 | `{ "id": "<페이지>", "type": "page" }` |
| 글이나 블록에 단 댓글 | `{ "id": "<블록>", "type": "block" }` |
| 답글 | 스레드 첫 댓글과 같습니다. |

행의 `data.parent.id`와 `data.parent.data_source_id`는 모두 데이터베이스 ID입니다.

글에 단 댓글의 `parent`는 다음과 같이 동작합니다.

* 저장된 본문을 기준으로 정합니다. 댓글 표식이 저장되기 전이면 `parent`가 페이지일 수 있습니다. 저장까지 최대 10초가 걸립니다. `GET /v1/comments`는 열린 본문을 읽으므로 블록으로 반환합니다.
* 표식이 본문에서 사라지면 이전 블록을 알 수 없어 `parent`가 페이지입니다.
* 하위 문서 카드의 글에 단 댓글은 `parent`가 `{문서 ID}.{블록}` 형식입니다. 블록 API는 그 카드를 `child_page`로 반환하므로 이 ID로 블록을 읽으면 404입니다. `GET /v1/comments`의 `block_id`로는 사용할 수 있습니다.

### updated\_properties

`page.properties_updated`에서는 속성 ID 문자열의 배열입니다.

* 제목은 `title`입니다. 다른 ID는 API가 반환하는 값 그대로입니다.
* 수식 속성은 나오지 않습니다.
* 관계 속성을 바꾸면 양쪽 행이 각자 이벤트를 받습니다. 연동이 읽지 못하는 데이터베이스를 가리키는 관계는 빠집니다.
* 값을 바꿨다가 60초 안에 되돌리면 빈 배열로 전송합니다.

`data_source.schema_updated`에서는 객체 배열입니다. 60초 안의 변경은 이벤트 하나로 합칩니다.

```json theme={null}
{
  "parent": {
    "id": "exampleDb001",
    "type": "database"
  },
  "updated_properties": [
    {
      "id": "exampleFld01",
      "name": "담당 팀",
      "action": "updated"
    },
    {
      "id": "exampleFld02",
      "name": "이전 메모",
      "action": "deleted"
    }
  ]
}
```

`action`은 `created` · `updated` · `deleted`입니다. 속성 2개를 만들면 `created` 2개가 이벤트 하나에 들어갑니다. 이름을 바꾸고 다른 속성을 지우면 `updated`와 `deleted`가 이벤트 하나에 들어갑니다. 선택지를 바꾸면 그 속성이 `updated`로 나옵니다.

### updated\_blocks

`{ id, type }` 객체의 배열입니다. `type`은 `block` · `page` · `database`이고, `page`와 `database`는 하위 문서와 인라인 데이터베이스입니다.

* 지운 블록과 새 하위 문서까지 들어갑니다. 지운 블록의 ID로 읽으면 404입니다.
* 60초 안에 고쳤다가 되돌린 블록도 들어갑니다.
* 연동이 읽지 못하는 문서와 데이터베이스는 빠집니다.
* 동기화 블록을 넣고 빼면 배열에 들어갑니다. 연동이 읽을 수 있는 블록만 들어갑니다.
* 버튼과 Bottari 노트 블록은 내용 비교에서 빠집니다. 앱 편집이 아닌 경로로 그 블록만 바뀌면 배열이 비어 있을 수 있습니다.

### 댓글 data

```json theme={null}
{
  "discussion_id": "exampleCmt01",
  "page_id": "exampleRow01",
  "parent": { "id": "exampleRow01", "type": "page" }
}
```

`entity.id`가 댓글 ID이고 `discussion_id`는 스레드 ID입니다. 스레드 첫 댓글은 두 값이 같습니다.

## 작성자

| 작성자 | `authors` 항목 |
| - | - |
| 사람 | `{ "id": "<사람>", "type": "person" }` |
| 연동 | `{ "id": "<봇>", "type": "bot" }` |
| 자동화 · 작성자를 알 수 없는 변경 | `{ "id": "00000000-0000-0000-0000-000000000000", "type": "bot" }` |

변경이 합쳐지면 작성자가 작성 순서대로 한 번씩 들어갑니다. 작업 에이전트와 세션이 쓴 변경의 작성자는 세션 소유자이고 `type`은 `person`입니다.

> [!WARNING]
>
> 연동이 직접 쓴 변경도 이벤트로 전송합니다. 이벤트를 받아 다시 쓰는 서버는 `authors`에 `GET /v1/users/me`의 봇 ID만 있는 이벤트를 걸러 반복을 막으세요.

자동화가 쓴 행을 API로 읽으면 `last_edited_by`는 `00000000-0000-0000-0000-000000000003`입니다. 웹훅의 `authors` 값과 다릅니다.

## 이벤트를 전송하지 않는 경우

| 경우 | 동작 |
| - | - |
| 연결하지 않은 데이터베이스, 권한을 따로 정한 행 | 이벤트가 없습니다. |
| 아이콘이나 표지만 변경 | 이벤트가 없습니다. |
| 같은 값 다시 쓰기 | 이벤트가 없습니다. |
| 행 순서 변경, 보관, 스페이스 이동 | 이벤트가 없습니다. |
| 선택지를 지워 행의 값이 바뀜 | 행 이벤트 없이 `data_source.schema_updated`만 전송합니다. |
| 속성을 바꾸거나 지워 행의 값이 한꺼번에 바뀜 | 행 이벤트가 없습니다. |
| 댓글 해결 | 이벤트가 없습니다. |
| 블록을 지워 그 블록의 댓글이 사라짐 | 댓글 이벤트가 없습니다. |
| 문서를 지워 댓글이 사라짐 | 댓글 이벤트가 없습니다. |
| 동기화 블록 안쪽 고치기 | 이벤트가 없습니다. |
| 가져오기로 쓴 관계 값 | 이벤트가 없습니다. |
| 가져오기로 새로 만든 인라인 데이터베이스의 행 | `page.created` 없이 `database.created`만 전송합니다. |
| 연결 끊기 | 끊겼음을 알리는 이벤트가 없습니다. |

보기와 파일 업로드 이벤트는 없습니다.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.