Conversational Answer Generation API (V2)
Related documentation
Purpose
This API forwards user messages and returns AI responses.
The v2 API can issue a new session on the server if session_id is absent.
Requests with the same session_id can continue the previous conversation.
Use chat_log_uuid included in the response to save Helpful / Not Helpful feedback for that conversation.
1. Chat Response Generation API
URL
HTTP method
Plain Text
POSTHeaders
| Headers | Value | Description |
|---|---|---|
| Content-Type | application/json | Indicates that the request body is JSON. |
| Authorization | Bearer <api_key> | Use the API key provided in the Sidetalk dashboard. |
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| messages | Array | Yes | The message array. Only the last role: "user" message is used as the actual question. |
| stream | Boolean | No | Whether to receive a streamed response. Defaults to false. |
| session_id | String | No | The conversation session ID. The server issues one if absent. |
| sessionId | String | No | An alias for session_id. |
| recommendedQuestions | Boolean | No | If true, includes suggested questions in the response. Defaults to false. |
How messages is used
messages is sent as an array, but the server does not accept the entire conversation history from the request body.
Only the last role: "user" message in the messages array is used as the actual question.
Conversation history is not sent in messages each time. The server uses history stored under session_id.
For example, only the last user message in the request below is used as the actual question.
JSON
{
"messages": [
{
"role": "user",
"content": "첫 질문"
},
{
"role": "assistant",
"content": "이전 답변"
},
{
"role": "user",
"content": "마지막 질문"
}
]
}Value used as the actual question:
JSON
{
"role": "user",
"content": "마지막 질문"
}session_id policy
In v2, the server can issue session_id.
| Situation | Behavior |
|---|---|
| No session_id | The server creates a new session_id and includes it in the response. |
| session_id provided and valid | Continues using the conversation history for that session. |
| session_id provided with an invalid format | Returns an error. |
| session_id provided but does not exist | Returns an error. |
The recommended approach is:
- Make the first request without session_id.
- Save session_id from the response.
- Pass the same session_id in subsequent conversation requests.
recommendedQuestions policy
recommendedQuestions is optional.
| Request condition | Response behavior |
|---|---|
| Omitted or false | Does not return suggested questions. |
| true with suggestions available | Includes suggested questions in the response. |
| true with no suggestions available | Returns recommended_questions: []. |
The server automatically looks up suggested questions based on the last role: "user" message.
With stream: false, they are returned in the top-level recommended_questions array.
With stream: true, look for a chunk whose sidetalk_event.type is recommendedQuestions and get the suggestions from sidetalk_event.data.items.
Suggested question identifiers are returned as knowledgeId.
Example request
Start a new conversation
JSON
curl -X POST https://api.sidetalk.ai/v2/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"messages": [
{
"role": "user",
"content": "안녕하세요, 도움이 필요해요."
}
],
"stream": false
}'Continue an existing session
JSON
curl -X POST https://api.sidetalk.ai/v2/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"messages": [
{
"role": "user",
"content": "이전 대화 내용 기준으로 다시 설명해줘."
}
],
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"stream": false
}'Include suggested questions
JSON
curl -X POST https://api.sidetalk.ai/v2/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"messages": [
{
"role": "user",
"content": "사이드톡이 뭐야?"
}
],
"stream": false,
"recommendedQuestions": true
}'Response format
Responses are provided in two ways depending on stream.
1-1. JSON response (stream: false or omitted)
Basic response example
JSON
{
"success": true,
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion",
"created": 1783928563,
"model": "sidetalk",
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "안녕하세요, 무엇을 도와드릴까요?"
},
"finish_reason": "stop"
}
]
}Response fields
| Field | Type | Description |
|---|---|---|
| success | Boolean | Whether the request succeeded. |
| id | String | The response ID, including the chatcmpl- prefix and chat_log_uuid. |
| object | String | The response object type. Returns chat.completion. |
| created | Number | The response creation time in Unix timestamp format. |
| model | String | The response model name. Defaults to sidetalk. |
| session_id | String | The conversation session ID, used for subsequent requests. |
| chat_log_uuid | String | The conversation log UUID, used to save feedback. |
| choices | Array | The list of response choices. |
| choices[0].index | Number | The index of the response choice. |
| choices[0].message.role | String | The response role, usually assistant. |
| choices[0].message.content | String | The full AI response text. |
| choices[0].finish_reason | String | The reason the response ended. Returns stop on normal completion. |
| recommended_questions | Array | Suggested questions returned only with recommendedQuestions: true. Returns up to three items or an empty array if none are found. | |
Suggested questions response example
JSON
{
"success": true,
"id": "chatcmpl-example",
"object": "chat.completion",
"created": 1787101993,
"model": "sidetalk",
"session_id": "4b025ddd-6a58-451a-9c29-6f221aa7bc9",
"chat_log_uuid": "a5c88ab2-c7cf-412f-b080-dc6ba74ebeee",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "사이드톡은 질문에 답변하는 AI 서비스입니다."
},
"finish_reason": "stop"
}
],
"recommended_questions": [
{
"knowledgeId": "3356",
"question": "추천 질문1",
"type": "chat_data"
},
{
"knowledgeId": "3357",
"question": "추천 질문2",
"type": "chat_data"
},
{
"knowledgeId": "3358",
"question": "추천 질문3",
"type": "chat_data"
}
]
}Suggested question item fields
| Field | Type | Description |
|---|---|---|
| recommended_questions[].knowledgeId | String | The ID identifying a suggested question. |
| recommended_questions[].question | String | The suggested question text shown to users. |
| recommended_questions[].type | String | The source type of the suggested question. Examples: chat_data, notion, file, file_pdf |
1-2. Streamed response (stream: true)
Responses are delivered in SSE (Server-Sent Events) format.
The stream first returns one metadata event, then returns answer fragments in order.
Main event types
| Event name | Description |
|---|---|
| metadata | Metadata containing the session ID and conversation log UUID. |
| message | A fragment of a regular text response. |
| showCard | Card response data. |
| inputForm | Form data. |
| reservationBookingForm | Reservation booking form data. |
| reservationLookupForm | Reservation lookup form data. |
| pageRedirect | Link data for page navigation. |
metadata event data structure
| Field | Type | Description |
|---|---|---|
| session_id | String | The current conversation session ID. |
| chat_log_uuid | String | The current conversation log UUID. |
metadata event example
JSON
event: metadata
data: {"session_id":"943f15db-3984-4f21-ad64-f0115839c3a6","chat_log_uuid":"2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3"}message event data structure
| Field | Type | Description |
|---|---|---|
| id | String | The response ID. |
| object | String | The response chunk object type. Returns chat.completion.chunk. |
| created | Number | The response creation time in Unix timestamp format. |
| model | String | The response model name. Defaults to sidetalk. |
| choices | Array | The list of response chunks. |
| choices[0].index | Number | The index of the response choice. |
| choices[0].delta.content | String | Part of the AI response text. |
| choices[0].finish_reason | String or null | The finish reason: null while in progress, stop on completion. |
Streamed response example
JSON
event: metadata
data: {"session_id":"943f15db-3984-4f21-ad64-f0115839c3a6","chat_log_uuid":"2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3"}
data: {"id":"chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3","object":"chat.completion.chunk","created":1783928563,"model":"sidetalk","choices":[{"index":0,"delta":{"content":"안녕하세요, "},"finish_reason":null}]}
data: {"id":"chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3","object":"chat.completion.chunk","created":1783928563,"model":"sidetalk","choices":[{"index":0,"delta":{"content":"무엇을 도와드릴까요?"},"finish_reason":null}]}
data: {"id":"chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3","object":"chat.completion.chunk","created":1783928563,"model":"sidetalk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE] Stream handling notes
- Events are separated by \n\n.
- event: metadata is sent once at the start of the stream.
- Regular text responses are included in choices[0].delta.content.
- finish_reason: stop indicates normal completion of answer generation.
- data: [DONE] indicates that the stream has fully ended.
- Save session_id because it is needed for subsequent conversation requests.
- Save chat_log_uuid because it is needed when calling the feedback API.
- showCard, inputForm, reservationBookingForm, reservationLookupForm, and pageRedirect contain structured agent response data rather than regular text.
- Look for a chunk whose sidetalk_event.type is recommendedQuestions.
- Get the suggested question list from sidetalk_event.data.items.
- The ID of a suggested question is knowledgeId.
1-3. Structured event responses
Chat responses may include structured events such as cards, input forms, reservation forms, and page navigation in addition to regular text.
Structured events are data that the client UI must handle separately, rather than regular answer text.
Supported event types are:
recommended_questions is not included by default. It is returned only when recommendedQuestions: true is explicitly requested. If recommendedQuestions is omitted or false, neither the suggested question field nor events are returned.
| type | Description |
|---|---|
| showCard | Card response data. |
| inputForm | User input form data. |
| reservationBookingForm | Reservation booking form data. |
| reservationLookupForm | Reservation lookup form data. |
| pageRedirect | Page navigation or link guidance data. |
| recommendedQuestions | Suggested question data, delivered only with stream:true. |
Structured events in JSON responses (stream: false)
With stream: false, structured events appear in the top-level sidetalk_events array.
sidetalk_events may be omitted when no structured events exist.
showCard example
JSON
{
"success": true,
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion",
"created": 1783928563,
"model": "sidetalk",
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "아래 정보를 확인해주세요."
},
"finish_reason": "stop"
}
],
"sidetalk_events": [
{
"type": "showCard",
"data": {
"title": "상품 안내",
"description": "추천 상품 목록입니다.",
"items": [
{
"title": "상품 A",
"description": "상품 A 설명",
"url": "https://example.com/product-a"
}
]
}
}
]
}inputForm example
JSON
{
"success": true,
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion",
"created": 1783928563,
"model": "sidetalk",
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "상담을 위해 아래 정보를 입력해주세요."
},
"finish_reason": "stop"
}
],
"sidetalk_events": [
{
"type": "inputForm",
"data": {
"title": "상담 정보 입력",
"fields": [
{
"name": "name",
"label": "이름",
"type": "text",
"required": true
},
{
"name": "phone",
"label": "연락처",
"type": "tel",
"required": true
}
]
}
}
]
}reservationBookingForm example
JSON
{
"success": true,
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion",
"created": 1783928563,
"model": "sidetalk",
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "예약을 위해 아래 정보를 입력해주세요."
},
"finish_reason": "stop"
}
],
"sidetalk_events": [
{
"type": "reservationBookingForm",
"data": {
"title": "예약하기",
"form_id": "reservation_01",
"fields": [
{
"name": "date",
"label": "예약일",
"type": "date",
"required": true
},
{
"name": "time",
"label": "예약 시간",
"type": "time",
"required": true
}
]
}
}
]
}reservationLookupForm example
JSON
{
"success": true,
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion",
"created": 1783928563,
"model": "sidetalk",
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "예약 조회를 위해 아래 정보를 입력해주세요."
},
"finish_reason": "stop"
}
],
"sidetalk_events": [
{
"type": "reservationLookupForm",
"data": {
"title": "예약 조회",
"fields": [
{
"name": "phone",
"label": "연락처",
"type": "tel",
"required": true
}
]
}
}
]
}pageRedirect example
JSON
{
"success": true,
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion",
"created": 1783928563,
"model": "sidetalk",
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "요청하신 페이지로 이동할 수 있습니다."
},
"finish_reason": "stop"
}
],
"sidetalk_events": [
{
"type": "pageRedirect",
"data": {
"url": "https://example.com/order",
"label": "주문 페이지로 이동"
}
}
]
}Structured events in streamed responses (stream: true)
With stream: true, structured events are also delivered as chat.completion.chunk.
Regular text is included in choices[0].delta.content.
Structured events are included in sidetalk_event.
showCard example
JSON
data: {
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion.chunk",
"created": 1783928563,
"model": "sidetalk",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": null
}
],
"sidetalk_event": {
"type": "showCard",
"data": {
"title": "상품 안내",
"description": "추천 상품 목록입니다.",
"items": [
{
"title": "상품 A",
"description": "상품 A 설명",
"url": "https://example.com/product-a"
}
]
}
}
}inputForm example
JSON
data: {
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion.chunk",
"created": 1783928563,
"model": "sidetalk",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": null
}
],
"sidetalk_event": {
"type": "inputForm",
"data": {
"title": "상담 정보 입력",
"fields": [
{
"name": "name",
"label": "이름",
"type": "text",
"required": true
},
{
"name": "phone",
"label": "연락처",
"type": "tel",
"required": true
}
]
}
}
}reservationBookingForm example
JSON
data: {
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion.chunk",
"created": 1783928563,
"model": "sidetalk",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": null
}
],
"sidetalk_event": {
"type": "reservationBookingForm",
"data": {
"title": "예약하기",
"form_id": "reservation_01",
"fields": [
{
"name": "date",
"label": "예약일",
"type": "date",
"required": true
},
{
"name": "time",
"label": "예약 시간",
"type": "time",
"required": true
}
]
}
}
}reservationLookupForm example
JSON
data: {
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion.chunk",
"created": 1783928563,
"model": "sidetalk",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": null
}
],
"sidetalk_event": {
"type": "reservationLookupForm",
"data": {
"title": "예약 조회",
"fields": [
{
"name": "phone",
"label": "연락처",
"type": "tel",
"required": true
}
]
}
}
}pageRedirect example
JSON
data: {
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion.chunk",
"created": 1783928563,
"model": "sidetalk",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": null
}
],
"sidetalk_event": {
"type": "pageRedirect",
"data": {
"url": "https://example.com/order",
"label": "주문 페이지로 이동"
}
}
}recommendedQuestions example
JSON
data: {
"id": "chatcmpl-2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"object": "chat.completion.chunk",
"created": 1783928563,
"model": "sidetalk",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": null
}
],
"sidetalk_event": {
"type": "recommendedQuestions",
"data": {
"items": [
{
"knowledgeId": "3356",
"question": "추천 질문1",
"type": "chat_data"
}
]
}
}
}Field descriptions
sidetalk_events
| Field | Type | Description |
|---|---|---|
| sidetalk_events | Array | The list of structured events. |
| sidetalk_events[].type | String | The event type. |
| sidetalk_events[].data | Object | Data for each event. |
sidetalk_event
| Field | Type | Description |
|---|---|---|
| sidetalk_event | Object | Structured event data. |
| sidetalk_event.type | String | The event type. |
| sidetalk_event.data | Object | Data for each event. |
Handling example
JavaScript
function handleSidetalkEvent(event) {
if (!event) return;
const eventType = event.type;
const eventData = event.data;
if (eventType === "showCard") {
console.log("카드 응답:", eventData);
}
if (eventType === "inputForm") {
console.log("입력 폼:", eventData);
}
if (eventType === "reservationBookingForm") {
console.log("예약 입력 폼:", eventData);
}
if (eventType === "reservationLookupForm") {
console.log("예약 조회 폼:", eventData);
}
if (eventType === "pageRedirect") {
console.log("페이지 이동:", eventData);
}
if (eventType === "recommendedQuestions") {
console.log("추천 질문:", eventData);
}
}Handle JSON responses
JavaScript
const events = data.sidetalk_events || [];
for (const event of events) {
handleSidetalkEvent(event);
}
//추천 질문
const recommendedQuestions = data.recommended_questions || [];
console.log("추천 질문:", recommendedQuestions);Handle streamed responses
JavaScript
if (data.sidetalk_event) {
handleSidetalkEvent(data.sidetalk_event);
}Cautions
- The data structure of structured events may vary with site, agent, and form settings.
- Clients should not assume a fixed structure for fields inside data.
- Handle regular text from choices[0].message.content or choices[0].delta.content.
- Handle structured events separately from sidetalk_events or sidetalk_event.
- With stream: false, suggested questions are returned in the top-level recommended_questions array.
- With stream: true, suggested questions are included in sidetalk_event.data.items.
- sidetalk_events is used in stream: false responses.
- sidetalk_event is used in each chunk of stream: true responses.
- The metadata event provides session information at the start of the stream.
- data: [DONE] means the stream has ended.
2. Conversation Feedback API
Use chat_log_uuid from the conversation response to save feedback for that conversation.
Even with v2 chat responses, the feedback API uses the existing path.
URL
Plain Text
https://api.sidetalk.ai/v1/chat/feedbackHTTP method
Plain Text
POSTHeaders
| Headers | Value | Description |
|---|---|---|
| Content-Type | application/json | Indicates that the request body is JSON. |
| Authorization | Bearer <api_key> | Use the API key provided in the Sidetalk dashboard. |
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| session_id | String | Yes | The session ID of the conversation whose feedback is being saved. |
| chat_log_uuid | String | Yes | The conversation UUID received from the v2 chat/completions response. |
| chat_log_feedback | String | Yes | Feedback value: 1 means helpful; 2 means not helpful. |
Example request
JSON
curl -X POST https://api.sidetalk.ai/v1/chat/feedback \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"session_id": "943f15db-3984-4f21-ad64-f0115839c3a6",
"chat_log_uuid": "2b9cc8fb-3cc6-4d40-aef6-d44af3d074f3",
"chat_log_feedback": "1"
}'Example success response
JSON
{
"success": true,
"updated": true,
"already_saved": false,
"feedback": "1"
}3. JavaScript examples
3-1. Handle JSON responses
JavaScript
async function sendMessageV2(message, sessionId = "") {
const response = await fetch("https://api.sidetalk.ai/v2/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer [API_KEY]"
},
body: JSON.stringify({
messages: [
{
role: "user",
content: message
}
],
session_id: sessionId,
stream: false
})
});
const data = await response.json();
if (!response.ok) {
console.error("Server Error:", data.error?.message || "Unknown error");
return null;
}
const answer = data.choices?.[0]?.message?.content || "";
const finishReason = data.choices?.[0]?.finish_reason || "";
const nextSessionId = data.session_id;
const chatLogUuid = data.chat_log_uuid;
console.log("AI 답변:", answer);
console.log("finish_reason:", finishReason);
console.log("session_id:", nextSessionId);
console.log("chat_log_uuid:", chatLogUuid);
return {
answer,
finishReason,
sessionId: nextSessionId,
chatLogUuid
};
}3-2. Handle streamed responses
JavaScript
async function sendMessageStreamV2(message, sessionId = "") {
const response = await fetch("https://api.sidetalk.ai/v2/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer [API_KEY]"
},
body: JSON.stringify({
messages: [
{
role: "user",
content: message
}
],
session_id: sessionId,
stream: true
})
});
if (!response.ok) {
const errorData = await response.json();
console.error("Server Error:", errorData.error?.message || "Unknown error");
return null;
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let savedSessionId = sessionId;
let savedChatLogUuid = "";
let fullAnswer = "";
let finishReason = "";
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const blocks = buffer.split("\n\n");
buffer = blocks.pop() || "";
for (const block of blocks) {
if (!block.trim()) continue;
const lines = block.split("\n");
let eventName = "message";
const dataLines = [];
for (const line of lines) {
if (line.startsWith("event:")) {
eventName = line.replace("event:", "").trim();
}
if (line.startsWith("data:")) {
dataLines.push(line.replace("data:", "").trimStart());
}
}
const dataStr = dataLines.join("\n").trim();
if (!dataStr) continue;
if (dataStr === "[DONE]") {
return {
answer: fullAnswer,
finishReason,
sessionId: savedSessionId,
chatLogUuid: savedChatLogUuid
};
}
const data = JSON.parse(dataStr);
if (eventName === "metadata") {
savedSessionId = data.session_id;
savedChatLogUuid = data.chat_log_uuid;
continue;
}
if (eventName === "message") {
const choice = data.choices?.[0] || {};
const chunk = choice.delta?.content || "";
if (chunk) {
fullAnswer += chunk;
console.log("chunk:", chunk);
}
if (choice.finish_reason) {
finishReason = choice.finish_reason;
console.log("finish_reason:", finishReason);
}
continue;
}
if (eventName === "showCard") {
console.log("showCard:", data);
}
if (eventName === "inputForm") {
console.log("inputForm:", data);
}
if (eventName === "pageRedirect") {
console.log("pageRedirect:", data);
}
}
}
return {
answer: fullAnswer,
finishReason,
sessionId: savedSessionId,
chatLogUuid: savedChatLogUuid
};
}3-3. Save feedback
JavaScript
async function sendFeedback({ sessionId, chatLogUuid, isHelpful }) {
const response = await fetch("https://api.sidetalk.ai/v1/chat/feedback", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer [API_KEY]"
},
body: JSON.stringify({
session_id: sessionId,
chat_log_uuid: chatLogUuid,
chat_log_feedback: isHelpful ? "1" : "2"
})
});
const data = await response.json();
if (!response.ok || !data.success) {
console.error("Feedback Error:", data.error || data.message || "Unknown error");
return null;
}
return data;
}4. Error responses
Errors in the v2 chat API are returned in the following format.
JSON
{
"error": {
"message": "messages is required",
"type": "invalid_request_error",
"code": "message_required"
}
}Error responses do not include choices or finish_reason.
Main error cases
| HTTP status | code | Description |
|---|---|---|
| 400 | message_required | messages is missing or contains no usable role: "user" message |
| 400 | invalid_session_id_format | session_id has an invalid format |
| 404 | session_id_not_found | The provided session_id does not exist for the current site |
| 403 | Authentication error | API authentication failure |
| 500 | server_error | An internal server error occurred |
5. Notes
- The actual question is the last role: "user" message in the messages array.
- Previous history is not passed in messages. The server uses history stored under session_id.
- If session_id is absent, the server issues a new one.
- Use the session_id issued by the server.
- If session_id is present, the server checks that the session exists for the current site.
- For streams, save session_id and chat_log_uuid from the metadata event first.
- Saving feedback requires both session_id and chat_log_uuid.
- v1 /v1/chat/completions retains its original response format for compatibility.
- Use /v2/chat/completions for automatic session creation and the v2 response structure.
