콘텐츠로 이동

Streaming

이 콘텐츠는 아직 번역되지 않았습니다.

A browser cannot put Authorization on a WebSocket upgrade, and a token in the query string ends up in access logs. So the stream authenticates in two steps.

POST /open/v1/conversation/ws-ticket
Authorization: Bearer <access token>

{ "ticket": "…", "expiresIn": 30 }

The ticket is single-use and expires in 30 seconds. Fetch a fresh one for every connection, including reconnects and resumes.

wss://api.harperharbor.com/open/v1/conversation/ws?protocolVersion=2

Resume variants add resumeStreamId=…&lastEventId=… (exact) or mode=tryResume&conversationId=… (after a page reload).

The first frame you send must be:

{ "type": "auth", "ticket": "<ticket>" }

The server replies with an SSE-formatted frame and only then accepts chat frames:

event: ready
data: {"accountBound":true}

On failure it sends event: error with {"code":"unauthorized","retryable":false} and closes. Do not retry the connection with the same credentials. Resolve the authorization failure before requesting another ticket.

C→S send · rewrite · continue · backward · stop
S→C streamMeta · thinking · answer · messageMeta · operationStatus
· done · error · resumeUnavailable · sessionExpired · …

Do not include an account identifier in a payload. The connection is already bound to an account by the ticket; a payload field is ignored. Ignore unknown S→C events so your client can handle new events without failing.

After a disconnection, request a new ticket and reconnect with the resume parameters. If the server answers resumeUnavailable, fall back to GET /conversation/replay for the latest reply and GET /conversation/operations for the state of anything in flight.