इसे छोड़कर कंटेंट पर जाएं

WebSocket इवेंट्स

연결

인간 WebSocket

GET wss://api.hashee.ai/ws/human

업그레이드 후 5초 이내에 인증을 전송하세요:

{ "type": "auth", "token": "<access_token>" }

에이전트 WebSocket

GET wss://api.hashee.ai/ws/agent?agent_id={agentId}

업그레이드 후 5초 이내에 인증을 전송하세요:

{ "type": "auth", "token": "hsk_...", "agent_id": "{agentId}" }

인증 응답

성공:

{ "type": "auth.ok" }

실패:

{
"type": "auth.error",
"reason": "invalid_token",
"message": "Token expired",
"i18n_key": "error.auth.expired"
}

클라이언트→서버 프레임

auth.renew

기존 연결에서 액세스 토큰을 갱신합니다. REST를 통해 JWT를 갱신한 후 전송하세요:

{ "type": "auth.renew", "access_token": "new_jwt..." }

서버→클라이언트 이벤트

메시지 이벤트

message.new

대화에 새 메시지:

{
"type": "message.new",
"conversation_id": "uuid",
"message_id": "uuid",
"sender_id": "uuid",
"sender_type": "human",
"content_type": "text",
"encrypted_payload": "base64...",
"conversation_seq": 42,
"created_at": "2026-01-01T00:00:00Z"
}

message.ack

전송된 메시지가 서버에 수신되었음을 확인합니다.

message.read

참가자가 특정 시퀀스 번호까지 메시지를 읽었습니다.

message.recalled

발신자가 메시지를 회수했습니다:

{
"type": "message.recalled",
"message_id": "uuid",
"conversation_id": "uuid",
"recalled_by": "uuid"
}

message.status_updated

메시지 전달 상태가 변경되었습니다.

message.pinned

그룹에서 메시지가 고정되었습니다.

스트림 이벤트

stream.start

에이전트가 스트리밍 응답을 시작했습니다.

stream.delta

스트리밍 콘텐츠의 청크:

{
"type": "stream.delta",
"conversation_id": "uuid",
"encrypted_payload": "base64..."
}

stream.done

영속화를 위한 전체 암호화 페이로드와 함께 스트림이 완료되었습니다.

stream.abort

에이전트가 스트림을 취소했습니다.

stream.error

스트림이 타임아웃되었거나 제한에 도달했습니다.

관계 이벤트

relation.established

새 사용자가 에이전트 사용을 시작했습니다:

{
"type": "relation.established",
"payload": {
"user_id": "uuid",
"display_name": "Alice",
"avatar_url": "https://...",
"language": "en",
"referral_source": "invite_link",
"public_key": "base64..."
}
}

SDK가 이 이벤트에서 public_key를 자동으로 캐시합니다.

relation.terminated

사용자가 에이전트와 연결을 끊었습니다:

{ "type": "relation.terminated", "payload": { "user_id": "uuid" } }

relation.suspended

사용자가 크리에이터에 의해 정지되었습니다:

{ "type": "relation.suspended", "payload": { "user_id": "uuid" } }

relation.restored

사용자가 크리에이터에 의해 복원되었습니다:

{ "type": "relation.restored", "payload": { "user_id": "uuid" } }

아티팩트 이벤트

artifact_response

사용자가 아티팩트에 응답했습니다 (양식 제출, 버튼 클릭):

{
"type": "artifact_response",
"payload": {
"conversation_id": "uuid",
"message_id": "uuid",
"ref_artifact": "artifact_id",
"ref_action": "submit",
"based_on_revision": 1,
"values": { "name": "My Project" }
}
}

artifact_update

에이전트가 아티팩트를 업데이트했습니다 (인간 클라이언트에 WebSocket 전달).

artifact.expired

아티팩트의 TTL이 만료되었습니다:

{
"type": "artifact.expired",
"payload": {
"conversation_id": "uuid",
"message_id": "uuid",
"artifact_id": "uuid"
}
}

에이전트 이벤트

agent.governance

에이전트 거버넌스 상태가 변경되었습니다 (WebSocket 전용, Webhook으로 전달되지 않음):

{
"type": "agent.governance",
"payload": {
"agent_template_id": "uuid",
"governance_status": "suspended",
"reason": "Policy violation"
}
}

상태가 suspended 또는 banned이면 WebSocket 연결이 종료됩니다.

agent.status

에이전트 온라인/오프라인 상태가 변경되었습니다.

agent.typing

에이전트가 입력 중입니다.

반응 이벤트

reaction.update

메시지의 반응이 변경되었습니다 (집계 상태):

{
"type": "reaction.update",
"payload": {
"message_id": "uuid",
"reactions": [
{ "emoji": "thumbsup", "count": 3, "user_ids": ["uuid1", "uuid2", "uuid3"] }
]
}
}

그룹 이벤트

group.updated

그룹 정보가 변경되었습니다 (이름, 아바타, 설정):

{
"type": "group.updated",
"payload": {
"conversation_id": "uuid",
"changes": { "name": "New Group Name" }
}
}

세션 이벤트

auth.expiring

알림: 액세스 토큰이 곧 만료됩니다. 클라이언트는 REST를 통해 갱신하고 auth.renew를 전송해야 합니다:

{ "type": "auth.expiring", "expires_in_seconds": 60 }

session.invalidated

서버가 세션을 종료했습니다 (기기 제거, 비밀번호 변경 등):

{
"type": "session.invalidated",
"payload": {
"reason": "device_removed",
"message": "Session terminated",
"i18n_key": "error.session.invalidated"
}
}

error

일반 WebSocket 오류:

{
"type": "error",
"payload": {
"code": "RATE_LIMITED",
"message": "Too many requests",
"i18n_key": "error.rate_limited"
}
}

전송 방식별 이벤트 전달

이벤트WebSocketWebhook
message.new
relation.established
relation.terminated
relation.suspended
relation.restored
artifact_response
agent.governance아니오
reaction.update아니오
group.updated아니오
artifact.expired아니오
session.invalidated아니오
auth.expiring아니오

Long Polling은 Webhook과 동일한 이벤트 세트를 전달합니다.

다음 단계