메뉴얼 생성
메뉴얼을 생성합니다. content는 이 메뉴얼에서 사용할 항목의 유일한 정본입니다. @tool:<uuid>와 @manual:<uuid> 토큰에서 tool_ids와 linked_manual_ids를 계산합니다. 모든 built_in_tools 항목은 content에서 @tool:<name> 토큰으로 호출해야 합니다. 호출하지 않은 항목은 제거합니다. 존재하지 않는 대상을 참조하면 요청을 거부합니다.
curl --request POST \
--url https://client-api.tryvox.co/v3/manuals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"trigger": "",
"content": "",
"built_in_tools": [
{
"toolType": "end_call",
"speakDuringExecution": {
"enabled": false,
"messages": [
"<string>"
]
},
"allowInterruptionDuringExecution": false,
"responseMode": "wait",
"name": "end_call",
"description": "<string>"
}
],
"config": {}
}
'import requests
url = "https://client-api.tryvox.co/v3/manuals"
payload = {
"name": "<string>",
"trigger": "",
"content": "",
"built_in_tools": [
{
"toolType": "end_call",
"speakDuringExecution": {
"enabled": False,
"messages": ["<string>"]
},
"allowInterruptionDuringExecution": False,
"responseMode": "wait",
"name": "end_call",
"description": "<string>"
}
],
"config": {}
}
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({
name: '<string>',
trigger: '',
content: '',
built_in_tools: [
{
toolType: 'end_call',
speakDuringExecution: {enabled: false, messages: ['<string>']},
allowInterruptionDuringExecution: false,
responseMode: 'wait',
name: 'end_call',
description: '<string>'
}
],
config: {}
})
};
fetch('https://client-api.tryvox.co/v3/manuals', 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/manuals",
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([
'name' => '<string>',
'trigger' => '',
'content' => '',
'built_in_tools' => [
[
'toolType' => 'end_call',
'speakDuringExecution' => [
'enabled' => false,
'messages' => [
'<string>'
]
],
'allowInterruptionDuringExecution' => false,
'responseMode' => 'wait',
'name' => 'end_call',
'description' => '<string>'
]
],
'config' => [
]
]),
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/manuals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"trigger\": \"\",\n \"content\": \"\",\n \"built_in_tools\": [\n {\n \"toolType\": \"end_call\",\n \"speakDuringExecution\": {\n \"enabled\": false,\n \"messages\": [\n \"<string>\"\n ]\n },\n \"allowInterruptionDuringExecution\": false,\n \"responseMode\": \"wait\",\n \"name\": \"end_call\",\n \"description\": \"<string>\"\n }\n ],\n \"config\": {}\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/manuals")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"trigger\": \"\",\n \"content\": \"\",\n \"built_in_tools\": [\n {\n \"toolType\": \"end_call\",\n \"speakDuringExecution\": {\n \"enabled\": false,\n \"messages\": [\n \"<string>\"\n ]\n },\n \"allowInterruptionDuringExecution\": false,\n \"responseMode\": \"wait\",\n \"name\": \"end_call\",\n \"description\": \"<string>\"\n }\n ],\n \"config\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.tryvox.co/v3/manuals")
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 \"name\": \"<string>\",\n \"trigger\": \"\",\n \"content\": \"\",\n \"built_in_tools\": [\n {\n \"toolType\": \"end_call\",\n \"speakDuringExecution\": {\n \"enabled\": false,\n \"messages\": [\n \"<string>\"\n ]\n },\n \"allowInterruptionDuringExecution\": false,\n \"responseMode\": \"wait\",\n \"name\": \"end_call\",\n \"description\": \"<string>\"\n }\n ],\n \"config\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"trigger": "<string>",
"content": "<string>",
"tool_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"built_in_tools": [
{
"toolType": "end_call",
"speakDuringExecution": {
"enabled": false,
"messages": [
"<string>"
]
},
"allowInterruptionDuringExecution": false,
"responseMode": "wait",
"name": "end_call",
"description": "<string>"
}
],
"linked_manual_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"config": {
"tool_call_sound": "none"
},
"created_at": 123,
"updated_at": 123
}{
"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": "RESOURCE_NOT_FOUND",
"message": "Resource not found.",
"details": {
"resource": "agent"
}
}
}{
"error": {
"code": "CONFLICT",
"message": "The requested operation conflicts with current state.",
"details": {
"current_status": "draft"
}
}
}{
"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
조직 API 키를 Authorization: Bearer <token> 형식으로 보냅니다.
Body
생성할 메뉴얼입니다.
POST /v3/manuals 생성 요청.
사용자에게 표시할 메뉴얼 이름입니다. 1~128자여야 합니다.
1 - 128통화 중 이 메뉴얼을 불러오는 자연어 트리거입니다.
메뉴얼 지침이며, 이 메뉴얼에서 사용할 항목의 유일한 정본입니다. 조직의 도구와 다른 메뉴얼은 @tool:<uuid>, @manual:<uuid>, @tool:<built-in name> 토큰으로 참조합니다. 이 토큰에서 tool_ids와 linked_manual_ids를 계산합니다. 모든 built_in_tools 항목은 여기에서 @tool:<name> 토큰으로 호출해야 합니다.
메뉴얼에 속한 built-in 도구 설정입니다. 각 name은 ^[a-zA-Z_][a-zA-Z0-9_]*$ 형식에 맞고 메뉴얼 안에서 고유해야 합니다. content에서 @tool:<name> 토큰으로 참조해야 합니다.
통화 종료 built-in 도구 설정입니다.
- EndCallTool
- TransferCallTool
- TransferAgentTool
- SendSmsTool
- SendDtmfTool
- SearchAddressTool
- SkillTool
Show child attributes
Show child attributes
메뉴얼 실행 옵션입니다. 생략하면 옵션 없이 메뉴얼을 생성합니다.
Show child attributes
Show child attributes
Response
성공 응답
manual 단건 응답(생성·조회·수정). organization_id·is_deleted 미노출.
메뉴얼 UUID입니다.
메뉴얼 이름입니다.
트리거 문구입니다.
참조 토큰을 원문 그대로 유지한 메뉴얼 지침입니다.
연결된 custom 도구 UUID입니다. content의 @tool:<uuid> 참조에서 계산합니다.
메뉴얼에 속한 built-in 도구 설정입니다.
통화 종료 built-in 도구 설정입니다.
- EndCallTool
- TransferCallTool
- TransferAgentTool
- SendSmsTool
- SendDtmfTool
- SearchAddressTool
- SkillTool
Show child attributes
Show child attributes
연결된 메뉴얼 UUID입니다. content의 @manual:<uuid> 참조에서 계산합니다.
메뉴얼 실행 옵션입니다. 응답에 항상 포함하며, 설정하지 않은 옵션은 null로 반환합니다.
Show child attributes
Show child attributes
리소스 생성 시각입니다. unix milliseconds 형식입니다.
리소스 마지막 수정 시각입니다. unix milliseconds 형식입니다.
Was this page helpful?
curl --request POST \
--url https://client-api.tryvox.co/v3/manuals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"trigger": "",
"content": "",
"built_in_tools": [
{
"toolType": "end_call",
"speakDuringExecution": {
"enabled": false,
"messages": [
"<string>"
]
},
"allowInterruptionDuringExecution": false,
"responseMode": "wait",
"name": "end_call",
"description": "<string>"
}
],
"config": {}
}
'import requests
url = "https://client-api.tryvox.co/v3/manuals"
payload = {
"name": "<string>",
"trigger": "",
"content": "",
"built_in_tools": [
{
"toolType": "end_call",
"speakDuringExecution": {
"enabled": False,
"messages": ["<string>"]
},
"allowInterruptionDuringExecution": False,
"responseMode": "wait",
"name": "end_call",
"description": "<string>"
}
],
"config": {}
}
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({
name: '<string>',
trigger: '',
content: '',
built_in_tools: [
{
toolType: 'end_call',
speakDuringExecution: {enabled: false, messages: ['<string>']},
allowInterruptionDuringExecution: false,
responseMode: 'wait',
name: 'end_call',
description: '<string>'
}
],
config: {}
})
};
fetch('https://client-api.tryvox.co/v3/manuals', 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/manuals",
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([
'name' => '<string>',
'trigger' => '',
'content' => '',
'built_in_tools' => [
[
'toolType' => 'end_call',
'speakDuringExecution' => [
'enabled' => false,
'messages' => [
'<string>'
]
],
'allowInterruptionDuringExecution' => false,
'responseMode' => 'wait',
'name' => 'end_call',
'description' => '<string>'
]
],
'config' => [
]
]),
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/manuals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"trigger\": \"\",\n \"content\": \"\",\n \"built_in_tools\": [\n {\n \"toolType\": \"end_call\",\n \"speakDuringExecution\": {\n \"enabled\": false,\n \"messages\": [\n \"<string>\"\n ]\n },\n \"allowInterruptionDuringExecution\": false,\n \"responseMode\": \"wait\",\n \"name\": \"end_call\",\n \"description\": \"<string>\"\n }\n ],\n \"config\": {}\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/manuals")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"trigger\": \"\",\n \"content\": \"\",\n \"built_in_tools\": [\n {\n \"toolType\": \"end_call\",\n \"speakDuringExecution\": {\n \"enabled\": false,\n \"messages\": [\n \"<string>\"\n ]\n },\n \"allowInterruptionDuringExecution\": false,\n \"responseMode\": \"wait\",\n \"name\": \"end_call\",\n \"description\": \"<string>\"\n }\n ],\n \"config\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.tryvox.co/v3/manuals")
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 \"name\": \"<string>\",\n \"trigger\": \"\",\n \"content\": \"\",\n \"built_in_tools\": [\n {\n \"toolType\": \"end_call\",\n \"speakDuringExecution\": {\n \"enabled\": false,\n \"messages\": [\n \"<string>\"\n ]\n },\n \"allowInterruptionDuringExecution\": false,\n \"responseMode\": \"wait\",\n \"name\": \"end_call\",\n \"description\": \"<string>\"\n }\n ],\n \"config\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"trigger": "<string>",
"content": "<string>",
"tool_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"built_in_tools": [
{
"toolType": "end_call",
"speakDuringExecution": {
"enabled": false,
"messages": [
"<string>"
]
},
"allowInterruptionDuringExecution": false,
"responseMode": "wait",
"name": "end_call",
"description": "<string>"
}
],
"linked_manual_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"config": {
"tool_call_sound": "none"
},
"created_at": 123,
"updated_at": 123
}{
"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": "RESOURCE_NOT_FOUND",
"message": "Resource not found.",
"details": {
"resource": "agent"
}
}
}{
"error": {
"code": "CONFLICT",
"message": "The requested operation conflicts with current state.",
"details": {
"current_status": "draft"
}
}
}{
"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": {}
}
}