
# 이벤트 목록 조회

`GET /v1/events` · 권한 `events:read`

환경의 이벤트를 오래된 순서대로 반환합니다. 각 이벤트는 웹훅으로 전달되는 것과 같은 `id`를 가진 같은 문서입니다. 이벤트는 모든 요금제에서 30일 동안 보관됩니다.

시스템에서 웹훅을 받을 수 없거나 장애 후 누락된 이벤트를 채워야 할 때 이 엔드포인트를 사용하십시오. 마지막으로 처리한 `next_cursor`를 저장해 두고 그 지점부터 이어서 조회하십시오.

환경은 항상 API 키에서 결정됩니다. 환경을 지정하는 매개변수는 없습니다.

## 요청

| 매개변수 | 위치 | 필수 | 설명 |
|---|---|---|---|
| `after` | query | 아니요 | 이전 응답의 `next_cursor`, 또는 지금부터 기록되는 이벤트만 받으려면 `latest`. 지정하지 않으면 보관 중인 가장 오래된 이벤트부터 목록이 시작됩니다. |
| `types` | query | 아니요 | 쉼표로 구분한 이벤트 유형, 최대 20개(예: `user.created,user.deleted`). 지정하지 않으면 모든 유형이 반환됩니다. |
| `org_id` | query | 아니요 | 이 조직(`org_…`)의 이벤트만 반환합니다. |
| `limit` | query | 아니요 | 페이지 크기, 1~100. 기본값 20. |
| `payload` | query | 아니요 | `thin`(기본값) 또는 `full`. `full`은 `users:read` 권한도 필요합니다. 전체 페이로드를 사용할 수 있을 때까지 `full`은 thin 페이로드를 반환합니다. |
| `purpose` | query | 아니요 | `tail`(기본값) 또는 `webhooks_listen`. `webhooks_listen`은 `development` 및 `staging` 환경에서만 허용됩니다. |

## 응답

`200 OK`:

| 필드 | 설명 |
|---|---|
| `data` | 순서대로 정렬된 이벤트. 각 이벤트에는 환경 안에서 증가하는 `seq`가 있습니다. |
| `next_cursor` | 항상 포함됩니다. `data`가 비어 있더라도 다음 요청에서 `after`로 전달하십시오. |
| `has_more` | 뒤에 이벤트가 더 있으면 `true`입니다. 이 경우 바로 다시 요청하십시오. `false`이면 다시 폴링하기 전에 5~60초 기다리십시오. |

커서는 `types` 또는 `org_id`에 따라 달라지지 않습니다. 필터를 바꾸어도 같은 위치에서 이어서 조회할 수 있습니다. 커서는 발급된 환경에서만 동작합니다.

```json
{
  "data": [
    {
      "id": "evt_01j9xk3m7q8r2s4t6v8w0y2z4a",
      "type": "connection.deleted",
      "schema_version": 1,
      "environment_id": "env_01j9xk3m7q8r2s4t6v8w0y2z4e",
      "occurred_at": "2026-11-03T08:15:42.120Z",
      "recorded_at": "2026-11-03T08:15:42.140Z",
      "seq": 4182,
      "data": {
        "object": {"id": "conn_01j9xk3m7q8r2s4t6v8w0y2z4f", "status": "deleted"},
        "object_version": 2
      },
      "context": {"actor": {"type": "system"}, "request_id": "0192a6c1-7d3e-7a10-9b2c-3d4e5f607182"}
    }
  ],
  "next_cursor": "eyJ2IjoxfQ.c2lnbmF0dXJl",
  "has_more": false
}
```

## 예시: 새 이벤트 폴링

```bash
cursor=latest
while true; do
  page=$(curl -sS -G https://api.keenauth.com/v1/events \
    -H "Authorization: Bearer $KEENAUTH_API_KEY" \
    --data-urlencode "after=$cursor" --data-urlencode "limit=100")
  echo "$page" | jq -c '.data[]'
  cursor=$(echo "$page" | jq -r '.next_cursor')
  [ "$(echo "$page" | jq -r '.has_more')" = "true" ] || sleep 10
done
```

CLI에서도 `keenauth events tail`로 같은 작업을 수행할 수 있습니다.

## 오류

모든 오류는 안정적인 `code`를 포함한 `application/problem+json` 본문으로 반환됩니다.

| HTTP | `code` | 발생 조건 |
|---|---|---|
| 400 | `invalid_cursor` | 커서 형식이 잘못되었거나 다른 환경에서 발급되었습니다. |
| 401 | `unauthenticated` | API 키가 없거나, 잘못되었거나, 폐기되었습니다. |
| 403 | `insufficient_permissions` | 키에 `events:read` 권한이 없거나, `users:read` 권한 없이 `payload=full`을 요청했습니다. |
| 403 | `test_feature_not_in_production` | 프로덕션 환경에서 `purpose=webhooks_listen`을 요청했습니다. |
| 422 | `validation_failed` | 매개변수가 잘못되었거나 반복되었습니다. `errors[].pointer`에 해당 매개변수가 표시됩니다. |
| 429 | `rate_limited` | 요청 한도를 초과했습니다. `Retry-After`를 따르십시오. |
| 503 | `service_unavailable` | 의존 서비스를 일시적으로 사용할 수 없습니다. 나중에 다시 시도하십시오. |

## 개인정보

이 엔드포인트는 이벤트라는 개인정보를 다룹니다. [KeenAuth API의 개인정보](/docs/policies/personal-data)에서 저장되는 항목, 보관 기간, 삭제 방식을 확인하십시오. 어떤 필드에도 민감정보(건강, 생체 정보, 종교, 정치적 견해, 성적 지향)를 보내지 마십시오.
