본문으로 건너뛰기
Sursa Developers

POST/v1/chat

어시스턴트 답변 스트리밍(SSE)

chat

로드 밸런서 뒤에 API 인스턴스가 여러 개 있으면(api.<domain> 주소, 1.62.0), 답변과 그 이벤트 버퍼는 답변을 생성하는 인스턴스의 메모리에 있어요. Last-Event-ID 헤더로 스트림을 재개하는 기능은 그 인스턴스에서만 동작해요.

같은 request_id 값과 같은 대화로 반복한 요청이 답변이 끝난 뒤 다른 인스턴스에 도달하면, 질문을 다시 하지 않고 저장된 답변(token과 done, 이벤트 번호는 1부터)을 받아요. 답변을 아직 생성하는 중에 반복한 요청이 다른 인스턴스에 도달하면 진행 중인 생성을 멈추고 답변을 새로 만들어요. 이때도 두 번째 질문은 생기지 않아요. 새로 생성하지 않고 스트림을 재개하려면 같은 인스턴스와의 연결을 유지하거나 done 이벤트 뒤에 요청을 반복하세요.

인증

Authorization 헤더로 API 키를 보내세요: Authorization: Bearer <키>.

헤더 파라미터

  • X-View-Asstring

    admin 역할의 API 키만 쓸 수 있어요. <profile>[:viewer|verifier|editor] 형식의 데이터 프로필로 요청을 보내요(예: employee:viewer). 설치 키는 이 헤더를 쓸 수 없어요(403).

쿠키 파라미터

  • kb_view_asstring

    세션의 “View as” 모드(다른 사용자로 보기) 쿠키. POST /auth/view-as 요청으로 설정하고 DELETE /auth/view-as 요청으로 지워요.

요청 본문

application/json

객체: ChatRequest

  • messagesarray of ChatMessage필수

    items ≥ 1

  • collectionstring

    기본값: "default"

  • tagsarray of string | null
  • exportstring | null
  • card_idsarray of string | null

    items ≤ 50

  • streamboolean

    기본값: false

  • conversation_idstring | null

    length ≤ 64

  • originstring | null
  • toolsboolean | null
  • bypass_cacheboolean

    답변 캐시에서 답변을 가져오지 않아요(캐시된 답변 아래의 “Get a fresh answer” 버튼). 새 답변이 캐시 항목을 대체해요.

    기본값: false

  • languagestring | null

    답변 언어: 그 언어로 답변하려면 ISO 639-1 코드(de, en, ru, …)를 지정하세요. auto 값이거나 필드가 없으면 질문에서 언어를 감지해요. 웹 화면은 다른 언어로 된 제안의 언어를 명시적으로 전달해요(Starter.language).

  • scopeChatScope | null

    질문 범위: 여러 컬렉션, 소스, 태그, 기간. 범위의 컬렉션은 collection 값을 대체해요. 소스를 지정하면 답변이 그 소스의 컬렉션(과 그 소스 자체의 카드)으로 좁혀져요. 태그는 tags 값에 추가돼요. 기간은 재무 답변을 그 기간으로 제한해요. 사용자가 볼 수 있는 것만 선택할 수 있어요(컬렉션: collections.no_access/collections.not_found, 소스: sources.not_found). conversation_id 값이 있으면 범위가 대화에 저장돼요. 필드가 없으면 대화의 범위가 적용되고, null 또는 빈 범위는 대화의 범위를 지워요.

  • request_idstring

    질문의 멱등성 키. 한 질문에 대한 스트림의 모든 재시도에 같은 키를 보내세요(연결이 끊긴 뒤의 재시도. 이때 Last-Event-ID 헤더는 스트림을 이어 가지 않고 기록만 돼요). 이미 저장된 답변의 키로 재시도하면 두 번째 질문이 만들어지지 않아요: 질문 한도나 크레딧 한도가 소진되었더라도 저장된 결과를 done 이벤트 하나(와 텍스트가 담긴 token 이벤트)로 다시 보내요. 연결이 끊긴 클라이언트를 위해 이전 답변이 아직 생성 중이면 그 생성을 멈추고 답변을 새로 생성해요.

    length ≤ 64

  • version_ofinteger (int64)

    대화에서 이 질문 턴의 새 버전을 만들어요(대화 기록의 question_id 값): 수정한 질문(messages의 새 텍스트), 다시 생성한 답변(같은 텍스트, 보통 bypass_cache 사용), 또는 다른 quality 값으로 보낸 같은 질문(예: fast 답변 뒤의 precise). 이전 질문과 답변 쌍은 유지돼요. 그 뒤의 턴은 이전 버전의 브랜치에 남고, 새 버전이 선택된 동안에는 대화 기록에서 숨겨져요(FeedItem.versions, POST /v1/conversations/{conv_id}/versions). 답변에 쓰는 대화 이력은 이 턴까지의 선택된 브랜치예요. 버전의 quality 값은 대화 설정을 바꾸지 않아요. conversation_id 값이 필요하며, 다른 대화의 질문이면 404 questions.not_found 오류를 반환해요.

  • qualitystring

    결과를 찾는 검색의 속도와 정확도 사이의 균형: fast는 더 빠르고 precise는 더 정확해요. 기본값: precise.

    허용 값: fastprecise

응답

200`stream=true`이면 `text/event-stream`. 각 이벤트는 `id: <number>` 줄(스트림 안에서 이벤트의 순번, 1부터 시작)과 `data: <JSON>` 줄, 그리고 빈 줄로 이루어져요. `event:` 필드와 `retry:` 필드는 쓰지 않으며, 이벤트 유형은 `type` 필드(`ChatEvent`)에 있어요.

stream=true이면 text/event-stream. 각 이벤트는 id: <number> 줄(스트림 안에서 이벤트의 순번, 1부터 시작)과 data: <JSON> 줄, 그리고 빈 줄로 이루어져요. event: 필드와 retry: 필드는 쓰지 않으며, 이벤트 유형은 type 필드(ChatEvent)에 있어요.

request_id 값이 있는 질문은 연결과 관계없이 답변돼요. 연결이 끊겨도 답변은 멈추지 않고 끝까지 만들어져 대화에 저장돼요(최대 10분). 같은 요청(같은 request_id 값과 같은 대화)을 반복하면 진행 중인 답변에 연결되며, Last-Event-ID 헤더를 보내면 그 번호 다음의 이벤트를 받으므로 스트림이 같은 이벤트 번호로 이어져요. 그 번호부터 스트림을 이어 갈 수 없으면 반복한 요청은 스트림을 처음부터 받아요. 이때 첫 이벤트의 번호는 Last-Event-ID 값보다 크지 않으며, 클라이언트는 답변을 처음부터 다시 받아요. 답변이 이미 끝나 이벤트 버퍼가 해제되었으면(3분 뒤) 질문을 다시 하지 않고 저장된 결과를 다시 보내고(token과 done, 번호는 1부터), 그렇지 않으면 답변을 새로 생성해요. 이런 답변을 멈추려면 POST /v1/chat/cancel 요청을 보내세요. request_id 값이 없으면 클라이언트 연결이 끊길 때 답변이 취소돼요.

첫 이벤트 뒤 답변이 진행되는 동안 서버는 15초마다 : ping 주석을 보내요. 이 주석은 무시하세요. 이벤트 순서: stage 이벤트(진행 상황), meta, sources, data, 이어서 token 이벤트로 오는 답변 본문, 마지막으로 done. 답변 본문 전에 sources와 data가 반복될 수 있고 tool 이벤트가 나올 수 있으며, 본문은 token 하나로 오거나 여러 부분으로 나뉘어 올 수 있어요. 캐시된 답변: meta(cached 포함), sources, data, token, done. 스트림이 시작된 뒤 생긴 오류는 error 이벤트로 오며, 스트림은 done 없이 닫혀요. 스트림의 HTTP 상태는 항상 200이에요. done 뒤에는 후속 질문 제안을 담은 followups 이벤트가 올 수 있어요. 처리하지 않는 이벤트 유형은 무시하세요.

stream=false이면 AnswerResponse 본문(conversation_id 포함)을 담은 application/json.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: AnswerResponse

  • answerstring필수
  • question_idinteger필수
  • querystring
  • collectionstring필수
  • sourcesarray of Source필수
  • table_queriesarray of TableQuery필수
  • datasetsarray of Dataset필수
  • chartsarray of ChartSpec필수
  • warningsarray of AnswerWarning필수
  • timingsTimings필수
  • provenancearray of NumberProvenance
  • emptystring

    허용 값: no_hitsrestrictedguardrailno_data_for_period

  • verificationAnswerVerification
  • alt_periodsarray of AnswerAltPeriod

    items ≤ 6

  • drilldownarray of AnswerDrilldown

    items ≤ 20

  • restrictedRestrictedInfo
  • verified_onlyboolean
  • cachedboolean
  • out_of_scopeAnswerOutOfScope
  • attachmentsarray of Attachment
  • export_errorstring
  • toolsstring | null

    이 답변에 도구를 사용한 이유: request(명시적으로 요청함), compare, compute, action(질문에 따라), needs_calc(표에 대한 계산이 필요함), summary(컬렉션이나 문서의 개요), mcp(조직이 외부 MCP 서버를 연결함).

    허용 값: requestcomparecomputeactionneeds_calcsummarymcpnull

  • tool_callsarray of ToolCallInfo
  • calculationsarray of Calculation
  • pending_actionsarray of PendingAction
  • entitiesarray of AnswerEntity필수
  • followupsarray of Followup필수
  • conversation_idstring

    대화가 있는 POST /v1/chat 요청에만 있어요.

  • answer_idstring

    답변 객체의 ID.

400잘못된 요청이에요. 파라미터 값이나 객체의 상태 때문에 이 동작을 할 수 없어요(`detail` 필드에 메시지가 있어요).

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

401자격 증명(세션 쿠키나 API 키)을 보내지 않았거나 키를 찾을 수 없어요.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

403이 동작은 허용되지 않아요. 역할이 부족하거나, 컬렉션이나 카드에 접근할 수 없거나, 요청이 “View as” 모드로 실행 중이거나, 조직이 정지 또는 삭제된 경우예요(`detail` 필드는 `code: org_suspended | org_deleted` 값을 가진 객체예요).

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

404객체가 없거나 접근할 수 없어요. API는 접근이 제한된 객체가 존재하는지 확인해 주지 않아요.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

422유효성 검사 오류예요. 본문이나 파라미터가 스키마와 맞지 않거나(`detail` 필드는 유효성 검사 오류 목록), 파라미터 값이 허용 범위를 벗어났어요(`detail` 필드는 메시지).

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

429요청이 너무 많거나(`api.rate_limited`), 조직의 분·일·월 할당량을 다 썼거나(`api.quota_exceeded`, `error.details` 필드에 `quota`, `limit`, `reset_at` 값이 있어요), 조직의 한도에 도달했거나, 답변 서비스가 바쁜 상태예요(`answers.engine_busy`). `Retry-After` 헤더에 적힌 시간만큼 기다리세요.

응답 헤더

  • Retry-After

    요청을 다시 시도하기 전에 기다릴 초.

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

오류 코드

모든 요청에 공통으로 쓰이는 코드 외에 이 엔드포인트가 error.code로 반환할 수 있는 코드예요.

안전한 재시도

POST와 PATCH 요청마다 Idempotency-Key 헤더(예: UUID)를 보내세요. 24시간 안에 같은 키로 재시도하면 요청을 다시 실행하지 않고 저장된 응답을 반환해요.

호출 한도

응답에는 RateLimit, RateLimit-Policy 헤더와 이전 헤더인 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset이 담겨요. 429 응답에는 초 단위의 Retry-After 헤더가 있어요. 그만큼 기다린 뒤 재시도하세요.

← answers · API 레퍼런스