메뉴얼 수정
메뉴얼의 일부 필드를 수정합니다. 생략한 필드는 기존 값을 유지하며, 요청 본문이 비어 있으면 거부합니다. content를 변경하면 tool_ids와 linked_manual_ids를 다시 계산합니다. content에서 제거한 참조는 해당 배열에서도 제거합니다. content에서 더 이상 호출하지 않는 built_in_tools 항목도 제거합니다. 요청에서 built_in_tools를 생략해도 저장된 값은 갱신합니다.
curl --request PATCH \
--url https://client-api.tryvox.co/v3/manuals/{manual_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"trigger": "<string>",
"content": "<string>",
"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/{manual_id}"
payload = {
"name": "<string>",
"trigger": "<string>",
"content": "<string>",
"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.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
trigger: '<string>',
content: '<string>',
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/{manual_id}', 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/{manual_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'trigger' => '<string>',
'content' => '<string>',
'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/{manual_id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"trigger\": \"<string>\",\n \"content\": \"<string>\",\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("PATCH", 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.patch("https://client-api.tryvox.co/v3/manuals/{manual_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"trigger\": \"<string>\",\n \"content\": \"<string>\",\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/{manual_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"trigger\": \"<string>\",\n \"content\": \"<string>\",\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> 형식으로 보냅니다.
Path Parameters
메뉴얼 UUID입니다.
Body
수정할 메뉴얼 필드입니다.
PATCH /v3/manuals/{id} 부분 업데이트 요청.
보낸 필드만 반영한다(생략 = 변경 없음). 빈 body {} 는 400(PatchRequest).
각 필드는 null 을 허용하지 않는다 — null 전송 시 400.
메뉴얼 이름입니다. 1~128자여야 합니다. 생략하면 현재 값을 유지하며, null은 허용하지 않습니다.
1 - 128트리거 문구입니다. 생략하면 현재 값을 유지하며, null은 허용하지 않습니다.
메뉴얼 지침입니다. 생략하면 현재 값을 유지하며, null은 허용하지 않습니다. 값을 보내면 참조 토큰에서 tool_ids와 linked_manual_ids를 다시 계산합니다. 여기에서 제거한 참조는 해당 배열에서도 제거합니다.
built-in 도구 설정입니다. 생략하면 변경하지 않으며, null은 허용하지 않습니다. 각 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
메뉴얼 실행 옵션입니다. 생략하면 현재 값을 유지하며, null은 허용하지 않습니다. 보낸 옵션을 저장된 옵션에 병합합니다. 생략한 옵션은 저장된 값을 유지하고, 옵션을 null로 보내면 해당 옵션만 지웁니다.
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 PATCH \
--url https://client-api.tryvox.co/v3/manuals/{manual_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"trigger": "<string>",
"content": "<string>",
"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/{manual_id}"
payload = {
"name": "<string>",
"trigger": "<string>",
"content": "<string>",
"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.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
trigger: '<string>',
content: '<string>',
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/{manual_id}', 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/{manual_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'trigger' => '<string>',
'content' => '<string>',
'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/{manual_id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"trigger\": \"<string>\",\n \"content\": \"<string>\",\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("PATCH", 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.patch("https://client-api.tryvox.co/v3/manuals/{manual_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"trigger\": \"<string>\",\n \"content\": \"<string>\",\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/{manual_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"trigger\": \"<string>\",\n \"content\": \"<string>\",\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": {}
}
}