Skip to main content
GET
https://sajuapi.dev
/
v1
/
events
이벤트 스트림 (SSE)
curl --request GET \
  --url https://sajuapi.dev/v1/events \
  --header 'X-API-Key: <api-key>'
v1 Enterprise API (Coming Soon)이 엔드포인트는 Enterprise 버전에서 제공될 예정입니다. 현재는 v0 API를 사용하세요.
Server-Sent Events(SSE)를 통해 실시간 이벤트를 수신합니다. 웹훅의 대안으로, 클라이언트에서 직접 이벤트를 구독할 수 있습니다.
SSE는 단방향 스트리밍입니다. 양방향 통신이 필요하면 웹훅을 사용하세요.

Query 파라미터

events
string
수신할 이벤트 유형입니다. 쉼표로 구분합니다. 생략하면 모든 이벤트를 수신합니다.
profile_id
string
특정 프로필의 이벤트만 수신합니다.
last_event_id
string
마지막으로 수신한 이벤트 ID입니다. 연결이 끊어진 후 재연결 시 사용합니다.

Response

성공

연결에 성공하면 SSE 스트림이 시작됩니다. 이벤트는 text/event-stream 형식으로 전송됩니다.

실패

상태 코드에러 타입설명
401authentication_errorAPI 키가 유효하지 않음
429rate_limited동시 연결 수 초과

요청 예시

# 모든 이벤트 수신
curl -N -H "X-API-Key: bs_live_xxx" \
  "https://api.sajuapi.dev/v1/events"

# 특정 이벤트만 수신
curl -N -H "X-API-Key: bs_live_xxx" \
  "https://api.sajuapi.dev/v1/events?events=fortune.generated,fortune.cached"

# 특정 프로필 이벤트만 수신
curl -N -H "X-API-Key: bs_live_xxx" \
  "https://api.sajuapi.dev/v1/events?profile_id=prf_abc123def456"

이벤트 형식

SSE 이벤트는 다음 형식으로 전송됩니다.
event: fortune.generated
id: evt_abc123def456
data: {"type":"fortune.generated","fortune_id":"ftn_xyz789","profile_id":"prf_abc123","score":85,"timestamp":"2025-01-16T09:00:00Z"}

event: heartbeat
id: hb_1705395600
data: {"type":"heartbeat","timestamp":"2025-01-16T09:00:00Z"}

이벤트 유형

이벤트설명데이터
fortune.generated운세가 생성됨fortune_id, profile_id, score, model
fortune.cached캐시된 운세 반환fortune_id, profile_id
profile.created프로필이 생성됨profile_id, day_master
profile.updated프로필이 수정됨profile_id
profile.deleted프로필이 삭제됨profile_id
daily.reset일일 운세 리셋 (자정)date, profiles_count
heartbeat연결 유지 확인timestamp

응답 예시

fortune.generated

{
  "type": "fortune.generated",
  "fortune_id": "ftn_abc123def456",
  "profile_id": "prf_xyz789abc123",
  "fortune_type": "daily",
  "fortune_date": "2025-01-16",
  "score": 85,
  "model": "haiku",
  "cached": false,
  "timestamp": "2025-01-16T09:00:00Z"
}

daily.reset

{
  "type": "daily.reset",
  "date": "2025-01-17",
  "profiles_count": 5420,
  "cache_cleared": true,
  "timestamp": "2025-01-17T00:00:00+09:00"
}

heartbeat

{
  "type": "heartbeat",
  "timestamp": "2025-01-16T09:05:00Z"
}

React 통합 예시

import { useEffect, useState } from 'react';

function useEventStream(apiKey, events = []) {
  const [lastEvent, setLastEvent] = useState(null);
  const [connected, setConnected] = useState(false);

  useEffect(() => {
    const params = new URLSearchParams();
    if (events.length > 0) {
      params.set('events', events.join(','));
    }

    const eventSource = new EventSource(
      `https://api.sajuapi.dev/v1/events?${params}`,
      { headers: { 'X-API-Key': apiKey } }
    );

    eventSource.onopen = () => setConnected(true);
    eventSource.onerror = () => setConnected(false);

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);
      if (data.type !== 'heartbeat') {
        setLastEvent(data);
      }
    };

    return () => eventSource.close();
  }, [apiKey, events.join(',')]);

  return { lastEvent, connected };
}

// 사용 예시
function FortuneMonitor() {
  const { lastEvent, connected } = useEventStream(
    'bs_live_xxx',
    ['fortune.generated']
  );

  return (
    <div>
      <div>상태: {connected ? '연결됨' : '연결 끊김'}</div>
      {lastEvent && (
        <div>
          최근 이벤트: {lastEvent.type} - {lastEvent.fortune_id}
        </div>
      )}
    </div>
  );
}

재연결 처리

연결이 끊어지면 Last-Event-ID 헤더를 사용하여 누락된 이벤트를 복구할 수 있습니다.
let lastEventId = null;

function connect() {
  const url = new URL('https://api.sajuapi.dev/v1/events');
  if (lastEventId) {
    url.searchParams.set('last_event_id', lastEventId);
  }

  const eventSource = new EventSource(url, {
    headers: { 'X-API-Key': 'bs_live_xxx' }
  });

  eventSource.onmessage = (event) => {
    lastEventId = event.lastEventId;
    // 이벤트 처리
  };

  eventSource.onerror = () => {
    eventSource.close();
    // 5초 후 재연결
    setTimeout(connect, 5000);
  };
}
동시 SSE 연결 수는 API 키당 5개로 제한됩니다. 초과 시 가장 오래된 연결이 종료됩니다.

Heartbeat

서버는 30초마다 heartbeat 이벤트를 전송하여 연결을 유지합니다. 60초 이상 이벤트가 없으면 연결이 끊어진 것으로 간주하고 재연결하세요.
이벤트는 최대 5분간 버퍼링됩니다. 5분 이상 연결이 끊어지면 일부 이벤트가 손실될 수 있습니다. 중요한 이벤트는 웹훅을 사용하세요.