채팅
채팅 발신 메시지 전송
에이전트 턴을 실행하지 않고 고객에게 메시지 한 건을 보내 채팅의 채널로 전달합니다. origin=operator는 사람의 답장이며, 사람이 응대 중인 채팅에만 보낼 수 있습니다. 채팅을 사람에게 넘기는 작업은 POST /chats/{chat_id}/takeover입니다. 상담사로 등록된 대시보드 사용자는 이 채팅을 맡은 상담사여야 합니다. 그 밖의 대시보드 사용자, 워크스페이스 API 키, 워크스페이스 범위 관리자는 상담사 등록 없이 채팅을 넘겨받은 사람으로 답장합니다. origin=system은 안내 메시지이며, 워크스페이스 API 키나 내부 관리자 자격 증명이 필요합니다. 보낸 메시지는 대화록에 origin과 같은 role로 남습니다.
POST
/
chats
/
{chat_id}
/
outbound-messages
채팅 발신 메시지 전송
curl --request POST \
--url https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"origin": "operator",
"client_idempotency_key": "<string>",
"text": "<string>",
"images": [
{
"type": "file_key",
"file_key": "file_abc123"
}
],
"navertalk": {
"text_content": {
"text": "<string>",
"quick_reply": {
"button_list": [
{
"type": "TEXT",
"data": {
"title": "<string>",
"code": "<string>"
}
}
]
}
},
"composite_content": null
}
}
'import requests
url = "https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages"
payload = {
"origin": "operator",
"client_idempotency_key": "<string>",
"text": "<string>",
"images": [
{
"type": "file_key",
"file_key": "file_abc123"
}
],
"navertalk": {
"text_content": {
"text": "<string>",
"quick_reply": { "button_list": [
{
"type": "TEXT",
"data": {
"title": "<string>",
"code": "<string>"
}
}
] }
},
"composite_content": None
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
origin: 'operator',
client_idempotency_key: '<string>',
text: '<string>',
images: [{type: 'file_key', file_key: 'file_abc123'}],
navertalk: {
text_content: {
text: '<string>',
quick_reply: {button_list: [{type: 'TEXT', data: {title: '<string>', code: '<string>'}}]}
},
composite_content: null
}
})
};
fetch('https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'origin' => 'operator',
'client_idempotency_key' => '<string>',
'text' => '<string>',
'images' => [
[
'type' => 'file_key',
'file_key' => 'file_abc123'
]
],
'navertalk' => [
'text_content' => [
'text' => '<string>',
'quick_reply' => [
'button_list' => [
[
'type' => 'TEXT',
'data' => [
'title' => '<string>',
'code' => '<string>'
]
]
]
]
],
'composite_content' => null
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages"
payload := strings.NewReader("{\n \"origin\": \"operator\",\n \"client_idempotency_key\": \"<string>\",\n \"text\": \"<string>\",\n \"images\": [\n {\n \"type\": \"file_key\",\n \"file_key\": \"file_abc123\"\n }\n ],\n \"navertalk\": {\n \"text_content\": {\n \"text\": \"<string>\",\n \"quick_reply\": {\n \"button_list\": [\n {\n \"type\": \"TEXT\",\n \"data\": {\n \"title\": \"<string>\",\n \"code\": \"<string>\"\n }\n }\n ]\n }\n },\n \"composite_content\": null\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"origin\": \"operator\",\n \"client_idempotency_key\": \"<string>\",\n \"text\": \"<string>\",\n \"images\": [\n {\n \"type\": \"file_key\",\n \"file_key\": \"file_abc123\"\n }\n ],\n \"navertalk\": {\n \"text_content\": {\n \"text\": \"<string>\",\n \"quick_reply\": {\n \"button_list\": [\n {\n \"type\": \"TEXT\",\n \"data\": {\n \"title\": \"<string>\",\n \"code\": \"<string>\"\n }\n }\n ]\n }\n },\n \"composite_content\": null\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"origin\": \"operator\",\n \"client_idempotency_key\": \"<string>\",\n \"text\": \"<string>\",\n \"images\": [\n {\n \"type\": \"file_key\",\n \"file_key\": \"file_abc123\"\n }\n ],\n \"navertalk\": {\n \"text_content\": {\n \"text\": \"<string>\",\n \"quick_reply\": {\n \"button_list\": [\n {\n \"type\": \"TEXT\",\n \"data\": {\n \"title\": \"<string>\",\n \"code\": \"<string>\"\n }\n }\n ]\n }\n },\n \"composite_content\": null\n }\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"chat_id": "<string>",
"role": "operator",
"content": "<string>",
"delivery": {
"channel": "api",
"status": "stored",
"provider_message_ids": [
"<string>"
],
"error_code": "<string>",
"error_message": "<string>"
},
"attachments": [
{
"file_key": "<string>",
"mime_type": "<string>"
}
]
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"field": "name",
"reason": "must not be blank"
}
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required.",
"details": {}
}
}{
"error": {
"code": "FORBIDDEN",
"message": "Permission denied.",
"details": {}
}
}{
"error": {
"code": "CHAT_NOT_FOUND",
"message": "채팅을 찾을 수 없습니다.",
"details": {
"chat_id": "22222222-2222-4222-8222-222222222222"
}
}
}{
"error": {
"code": "CONFLICT",
"message": "The requested operation conflicts with current state.",
"details": {
"current_status": "draft"
}
}
}{
"error": {
"code": "PAYLOAD_TOO_LARGE",
"message": "요청 본문이 허용 크기를 초과했습니다.",
"details": {
"content_length": 11534336,
"max_bytes": 10485760
}
}
}{
"error": {
"code": "CONVERTED_FILE_TOO_LARGE",
"message": "Converted image size exceeds the 1 MB limit.",
"details": {
"converted_size_bytes": 1258291,
"max_bytes": 1048576
}
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests.",
"details": {
"limit": 10,
"window_seconds": 1,
"scope": "user"
}
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error.",
"details": {}
}
}{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Service temporarily unavailable.",
"details": {}
}
}Authorizations
BearerAuthSupabaseJwtBearer
Headers
Body
application/json
이 엔드포인트의 요청 데이터입니다.
메시지를 보내는 쪽입니다. 대화록과 응답의 role이 이 값이 됩니다. operator는 사람 상담사의 답장이며, 사람이 응대 중인 채팅에만 보낼 수 있습니다. 대시보드 로그인 사용자, 워크스페이스 API 키, 워크스페이스 범위 관리자가 보낼 수 있고, 대시보드 사용자가 상담사로 등록되어 있으면 그 상담사가 이 채팅을 응대 중이어야 합니다. system은 안내 메시지이며, 워크스페이스 API 키나 내부 관리자만 보낼 수 있습니다.
Available options:
operator, system Example:
"operator"
보낼 메시지 텍스트입니다.
Minimum string length:
1Response
성공 응답
Was this page helpful?
⌘I
채팅 발신 메시지 전송
curl --request POST \
--url https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"origin": "operator",
"client_idempotency_key": "<string>",
"text": "<string>",
"images": [
{
"type": "file_key",
"file_key": "file_abc123"
}
],
"navertalk": {
"text_content": {
"text": "<string>",
"quick_reply": {
"button_list": [
{
"type": "TEXT",
"data": {
"title": "<string>",
"code": "<string>"
}
}
]
}
},
"composite_content": null
}
}
'import requests
url = "https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages"
payload = {
"origin": "operator",
"client_idempotency_key": "<string>",
"text": "<string>",
"images": [
{
"type": "file_key",
"file_key": "file_abc123"
}
],
"navertalk": {
"text_content": {
"text": "<string>",
"quick_reply": { "button_list": [
{
"type": "TEXT",
"data": {
"title": "<string>",
"code": "<string>"
}
}
] }
},
"composite_content": None
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
origin: 'operator',
client_idempotency_key: '<string>',
text: '<string>',
images: [{type: 'file_key', file_key: 'file_abc123'}],
navertalk: {
text_content: {
text: '<string>',
quick_reply: {button_list: [{type: 'TEXT', data: {title: '<string>', code: '<string>'}}]}
},
composite_content: null
}
})
};
fetch('https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'origin' => 'operator',
'client_idempotency_key' => '<string>',
'text' => '<string>',
'images' => [
[
'type' => 'file_key',
'file_key' => 'file_abc123'
]
],
'navertalk' => [
'text_content' => [
'text' => '<string>',
'quick_reply' => [
'button_list' => [
[
'type' => 'TEXT',
'data' => [
'title' => '<string>',
'code' => '<string>'
]
]
]
]
],
'composite_content' => null
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages"
payload := strings.NewReader("{\n \"origin\": \"operator\",\n \"client_idempotency_key\": \"<string>\",\n \"text\": \"<string>\",\n \"images\": [\n {\n \"type\": \"file_key\",\n \"file_key\": \"file_abc123\"\n }\n ],\n \"navertalk\": {\n \"text_content\": {\n \"text\": \"<string>\",\n \"quick_reply\": {\n \"button_list\": [\n {\n \"type\": \"TEXT\",\n \"data\": {\n \"title\": \"<string>\",\n \"code\": \"<string>\"\n }\n }\n ]\n }\n },\n \"composite_content\": null\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"origin\": \"operator\",\n \"client_idempotency_key\": \"<string>\",\n \"text\": \"<string>\",\n \"images\": [\n {\n \"type\": \"file_key\",\n \"file_key\": \"file_abc123\"\n }\n ],\n \"navertalk\": {\n \"text_content\": {\n \"text\": \"<string>\",\n \"quick_reply\": {\n \"button_list\": [\n {\n \"type\": \"TEXT\",\n \"data\": {\n \"title\": \"<string>\",\n \"code\": \"<string>\"\n }\n }\n ]\n }\n },\n \"composite_content\": null\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.tryvox.co/v3/chats/{chat_id}/outbound-messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"origin\": \"operator\",\n \"client_idempotency_key\": \"<string>\",\n \"text\": \"<string>\",\n \"images\": [\n {\n \"type\": \"file_key\",\n \"file_key\": \"file_abc123\"\n }\n ],\n \"navertalk\": {\n \"text_content\": {\n \"text\": \"<string>\",\n \"quick_reply\": {\n \"button_list\": [\n {\n \"type\": \"TEXT\",\n \"data\": {\n \"title\": \"<string>\",\n \"code\": \"<string>\"\n }\n }\n ]\n }\n },\n \"composite_content\": null\n }\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"chat_id": "<string>",
"role": "operator",
"content": "<string>",
"delivery": {
"channel": "api",
"status": "stored",
"provider_message_ids": [
"<string>"
],
"error_code": "<string>",
"error_message": "<string>"
},
"attachments": [
{
"file_key": "<string>",
"mime_type": "<string>"
}
]
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"field": "name",
"reason": "must not be blank"
}
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required.",
"details": {}
}
}{
"error": {
"code": "FORBIDDEN",
"message": "Permission denied.",
"details": {}
}
}{
"error": {
"code": "CHAT_NOT_FOUND",
"message": "채팅을 찾을 수 없습니다.",
"details": {
"chat_id": "22222222-2222-4222-8222-222222222222"
}
}
}{
"error": {
"code": "CONFLICT",
"message": "The requested operation conflicts with current state.",
"details": {
"current_status": "draft"
}
}
}{
"error": {
"code": "PAYLOAD_TOO_LARGE",
"message": "요청 본문이 허용 크기를 초과했습니다.",
"details": {
"content_length": 11534336,
"max_bytes": 10485760
}
}
}{
"error": {
"code": "CONVERTED_FILE_TOO_LARGE",
"message": "Converted image size exceeds the 1 MB limit.",
"details": {
"converted_size_bytes": 1258291,
"max_bytes": 1048576
}
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests.",
"details": {
"limit": 10,
"window_seconds": 1,
"scope": "user"
}
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error.",
"details": {}
}
}{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Service temporarily unavailable.",
"details": {}
}
}