# AGENTS Source: https://docs.tryvox.co/AGENTS # vox.ai 문서 저장소 작업 규칙 vox.ai 제품 문서(Mintlify) 저장소다. 이 파일은 입구와 요약만 둔다. 글·구성·부품·그림 규칙의 정본은 `guide/`이고(입구는 `guide/index.md`), 이 요약과 `guide/`가 다르면 `guide/`를 따른다. *** ## 시작하기 전에 1. 페이지(`docs/**`, `changelog/**`, `api-reference/v3/introduction.mdx`)를 건드리기 전에 저장소 스킬 `.agents/skills/docs-page-rewrite`를 불러온다. 스킬은 다시 쓰기 순서(유형 판별, 섹션 제안, 제품 실측, 쓰기, 감수, 캡처, 렌더 확인)와 캡처 리그를 담고, 규칙은 `guide/`를 가리킨다. 2. `guide/index.md`의 「작업별로 읽을 문서」에서 이번 작업에 맞는 문서를 읽는다. 3. 커밋 전에 `python3 scripts/docs_lint.py --changed`와 `mint broken-links`를 돌린다. API 한국어를 고쳤으면 `python3 scripts/build_ko_openapi.py check`도 돌린다. ## 규칙 요약 ### 말투 (`guide/foundations/voice-and-tone.md`) * 해요체 한 가지다. 설명과 사실은 「\~해요」, 독자가 따라 할 동작은 「\~하세요」, vox에 연락하거나 부탁할 때는 「\~해 주세요」, 할 수 있는 일은 「\~할 수 있어요」다. * 「-시-」(「하실 수」, 「원하시면」), 「드려요」·「드립니다」를 쓰지 않는다. 독자를 「여러분」, 「회원님」으로 부르지 않는다. * 가이드·AI·SDK 탭, 변경 내역, 사이트 틀, API 소개 페이지가 대상이다. API 필드·엔드포인트 설명(`translations/ko.v3.json`)은 「\~입니다」로 둔다. * web 화면(합쇼체)과 다른 곳과 그 까닭은 `guide/foundations/voice-and-tone.md`의 표에 있다. ### 표기 (`guide/foundations/writing.md`) * 줄표 `—`는 문장, 목록, 표, alt 어디에도 쓰지 않는다. 목록 구분은 `- **X**: 설명`, `- [링크](…): 설명`이다. * 「\~않아요」, 「\~없어요」 문장은 독자가 행동하거나 판단하는 데 필요할 때만 둔다(없어진 요구 사항, 쓸 수 있는지, 제품 제약). 당연히 그대로인 것과 범위 밖 덧말은 뺀다. * 화면 이름은 굵게, 메뉴 경로는 한 덩어리 `**설정 > 결제**`다. `→`로 잇지 않는다. * 개발자 개념은 페이지에서 처음 나올 때만 「함수 호출(Function Calling)」로 영어를 붙인다. 화면 이름에는 영어를 달지 않는다. * 보조 용언은 띄어 쓴다(「해 주세요」). 가운뎃점은 「·」만, 범위는 붙인 물결표(「3\~4일」), 전화번호는 붙임표(「070-1234-5678」)다. * 제품 이름은 늘 소문자 「vox.ai」다. 「VOX」, 「Vox」, 「voxai」로 쓰지 않는다(코드 식별자는 예외). 느낌표와 이모지를 쓰지 않는다. ### 용어 (`guide/foundations/terminology.md`) * 화면 이름과 용어의 정본은 web 저장소의 [`docs/design/foundations/glossary.md`](https://github.com/fleek-fitness/vox-web-frontend/blob/main/docs/design/foundations/glossary.md)다. * docs에만 있는 규칙: API 표면은 「SMS 발송」과 작업 제목의 「생성·조회·수정·삭제」, 가이드 본문은 「문자 발신」과 「만들기」. API 한국어는 「워크스페이스」, 「대량 발신」, 「대시보드」를 쓰고 첫 등장만 「워크스페이스(`organization_id`)」로 적는다. 「상담사」, 「메뉴얼」로 쓰고 「상담원」, 「매뉴얼」, 「캠페인」 같은 옛 이름은 `keywords`에만 둔다. ### 페이지 (`guide/pages/page-types.md`, `guide/pages/anatomy.md`) * 페이지마다 유형을 하나 정하고 유형별 고정 섹션을 둔다: 언제 사용하나요, 할 일 「\~하기」, 통화에서 일어나는 일, 문제가 생겼을 때, 관련 문서. 질문꼴 H2는 「언제 사용하나요」 하나뿐이다. * `description`은 이 기능으로 할 수 있는 일을 해요체 한 문장으로 쓴다(「…넘길 수 있어요.」). Mintlify가 제목 아래 리드로 보인다. * 「연관 검색어」 아코디언은 두지 않는다. 동의어와 옛 이름은 frontmatter `keywords` 배열에 둔다. * 화면 가이드는 본문 200~~400어절, 표 0~~2개다. 계약·규칙 페이지는 제한이 없다. * 사이드바 이름은 제품 사이드바를 따른다(구축, 배포, 보이스, 고객 메모리, 홈, 설정). 제목만 바꾸고 slug는 그대로 둔다. ### 부품 (`guide/components/`) * 카드는 고르거나 보낼 때만, 모든 카드에 `href`. 본문은 얻는 것과 언제 고르는지 두 문장. * ``는 설정·설치 절차에 한 블록, 3\~5단계. 단계 제목은 「\~하기」. * 아코디언 제목은 증상이면 해요체 문장(「통화가 연결되지 않아요」), 질문이면 「\~나요?」. * 콜아웃은 ``(흐름 밖 사실)와 ``(되돌릴 수 없음, 과금, 데이터 삭제) 두 가지, 페이지당 두 개까지. 절차와 링크 안내는 콜아웃에 넣지 않는다. * 표는 닫힌 집합에만. Tabs는 동작이 다른 모드, CodeGroup은 짝이 되는 코드. ### 그림 (`guide/visuals/`) * 캡처는 라이트 테마, 콘텐츠 영역이나 패널만, `borderRadius: "0.5rem"`, `` 없음. `maxWidth`는 480px, 640px, 896px만. * 이미지는 webp다. 캡처는 `images/screens/<문서 경로 그대로>/`(단 `docs/build/`는 `images/screens/agent-build/`. Mintlify가 `build` 폴더를 올리지 않는다), 일러스트는 `images/illustrations/<섹션>/`에 둔다. `{/* screenshot */}` 자리 표시를 남기지 않는다. * Mermaid는 gantt 타임라인과 여러 주체의 sequenceDiagram만 쓴다. 본문을 다시 그린 flowchart는 두지 않는다. ### 변경 내역과 API 참조 (`guide/pages/changelog.md`, `guide/pages/api-reference.md`) * 변경 내역은 월별 파일, 명사 제목, 과거형 해요체 본문(「\~할 수 있게 됐어요」), 항목 끝에 가이드 링크 한 줄이다. 지난 항목도 같은 꼴로 고친다. * API 작업 제목을 바꾸면 주소가 바뀌므로 같은 PR에서 `docs.json` `redirects`를 더한다. ## 저장소 운영 ### 로컬 확인 | 명령 | 쓰임 | | - | - | | `mint dev` | localhost:3000 미리보기. 연속으로 고친 뒤에는 옛 빌드가 뜰 수 있으니 새로 쓴 제목이 보이는지 확인한다 | | `mint broken-links` | 내부 링크 확인. 커밋 전에 돌린다 | | `mint a11y` | 빠진 alt 같은 접근성 확인 | | `python3 scripts/docs_lint.py --changed` | 바뀐 파일의 기계 규칙 확인 | Mintlify 일반 사용법은 `MINTLIFY.md`를 본다. ### API 참조 파이프라인 한국어 API 참조는 `translations/README.md`가 정본이다. * api-server의 영문 스펙을 `python3 scripts/build_ko_openapi.py fetch`로 `api-reference/v3/openapi.base.json`에 미러하고, `build`가 `translations/ko.v3.json`을 입혀 `api-reference/v3/openapi.json`을 만든다. * 한국어는 `translations/ko.v3.json`에서만 고친다. 고친 뒤 `build`로 다시 만들고 `check`로 확인한다. * `docs.json`의 v3 nav가 발행 목록이다. 발행하지 않는 작업은 `translations/publication.v3.json`에 사유와 함께 적는다. ### 손으로 고치지 않는 파일 | 파일 | 까닭 | | - | - | | `api-reference/v3/openapi.json` | `build`가 만드는 발행 스펙이다. CI가 재생성 결과와 바이트 단위로 대조한다 | | `api-reference/v3/openapi.base.json` | `fetch`가 갱신하는 영문 미러다 | | `build/` | drift 리포트 같은 빌드 산출물이다. git이 무시한다 | ### CI | 워크플로 | 하는 일 | | - | - | | `.github/workflows/openapi-ko.yml` | PR과 main push마다 `build_ko_openapi.py check`(발행 분류, 번역 완전성, 재생성 일치). 매일 03:00 KST에 prod 스펙과 `nightly` drift 확인 | | `.github/workflows/docs-lint.yml` | 모든 PR에서 바뀐 파일에 `scripts/docs_lint.py` | ### 사이트에서 빼는 파일 `.mintignore`가 `guide/`, `.agents/`, `_references/`를 사이트 빌드에서 뺀다. 이 폴더들의 Markdown은 사이트 페이지가 아니다. ### 검수 * 기계로 볼 수 있는 규칙은 lint가, 어체의 결처럼 판단이 필요한 규칙은 codex 리뷰가 본다. * PR마다 로컬 codex 리뷰(`codex exec -m gpt-6-astra -c model_reasoning_effort="medium" -c service_tier="default" -s read-only`) 결과를 PR 코멘트로 올리고, 확인된 지적만 고친다. * 머지는 PR마다 담당자의 승인을 받은 뒤에 한다. 캡처나 화면에 보이는 모양을 바꾸는 PR은 main과 PR의 같은 화면을 나란히 붙인다. * 스킬의 감수 단계(문체 패스, style-guide, humanize-korean, grammar-checker)는 스킬을 따른다. # MINTLIFY Source: https://docs.tryvox.co/MINTLIFY # Mintlify best practices **Always consult [mintlify.com/docs](https://mintlify.com/docs) for components, configuration, and latest features.** If you are not already connected to the Mintlify MCP server, [https://mintlify.com/docs/mcp](https://mintlify.com/docs/mcp), add it so that you can search more efficiently. Mintlify is a documentation platform that transforms MDX files into documentation sites. Configure site-wide settings in the `docs.json` file, write content in MDX with YAML frontmatter, and favor built-in components over custom components. Full schema at [mintlify.com/docs.json](https://mintlify.com/docs.json). ## Quick reference ### CLI commands * `npm i -g mint` - Install the Mintlify CLI * `mint dev` - Local preview at localhost:3000 * `mint broken-links` - Check internal links * `mint a11y` - Check for accessibility issues in content * `mint rename` - Rename/move files and update references * `mint validate` - Validate documentation builds ### Required files * `docs.json` - Site configuration (navigation, theme, integrations, etc.). See [global settings](https://mintlify.com/docs/settings/global) for all options. * `*.mdx` files - Documentation pages with YAML frontmatter ### Example file structure ``` project/ ├── docs.json # Site configuration ├── introduction.mdx ├── quickstart.mdx ├── guides/ │ └── example.mdx ├── openapi.yml # API specification ├── images/ # Static assets │ └── example.png └── snippets/ # Reusable components └── component.jsx ``` ## Organize content When a user asks about anything related to site-wide configurations, start by understanding the [global settings](https://www.mintlify.com/docs/organize/settings). See if a setting in the `docs.json` file can be updated to achieve what the user wants. ### Navigation The `navigation` property in `docs.json` controls site structure. Choose one primary pattern at the root level, then nest others within it. **Choose your primary pattern:** | Pattern | When to use | | - | - | | **Groups** | Default. Single audience, straightforward hierarchy | | **Tabs** | Distinct sections with different audiences (Guides vs API Reference) or content types | | **Anchors** | Want persistent section links at sidebar top. Good for separating docs from external resources | | **Dropdowns** | Multiple doc sections users switch between, but not distinct enough for tabs | | **Products** | Multi-product company with separate documentation per product | | **Versions** | Maintaining docs for multiple API/product versions simultaneously | | **Languages** | Localized content | **Within your primary pattern:** * **Groups** - Organize related pages. Can nest groups within groups, but keep hierarchy shallow * **Menus** - Add dropdown navigation within tabs for quick jumps to specific pages * **`expanded: false`** - Collapse nested groups by default. Use for reference sections users browse selectively * **`openapi`** - Auto-generate pages from OpenAPI spec. Add at group/tab level to inherit **Common combinations:** * Tabs containing groups (most common for docs with API reference) * Products containing tabs (multi-product SaaS) * Versions containing tabs (versioned API docs) * Anchors containing groups (simple docs with external resource links) ### Links and paths * **Internal links:** Root-relative, no extension: `/getting-started/quickstart` * **Images:** vox.ai docs store screenshots as webp under `/images/screens//` and illustrations under `/images/illustrations/
/`. See `guide/visuals/captures.md` * **External links:** Use full URLs, they open in new tabs automatically ## Customize docs sites **What to customize where:** * **Brand colors, fonts, logo** → `docs.json`. See [global settings](https://mintlify.com/docs/settings/global) * **Component styling, layout tweaks** → `custom.css` at project root * **Dark mode** → Enabled by default. Only disable with `"appearance": "light"` in `docs.json` if brand requires it Start with `docs.json`. Only add `custom.css` when you need styling that config doesn't support. ## Write content ### Components The [components overview](https://mintlify.com/docs/components) organizes all components by purpose: structure content, draw attention, show/hide content, document APIs, link to pages, and add visual context. Start there to find the right component. **Common decision points:** | Need | Use | | - | - | | Hide optional details | `` | | Long code examples | `` | | User chooses one option | `` | | Linked navigation cards | `` in `` | | Sequential instructions | `` | | Code in multiple languages | `` | | API parameters | `` | | API response fields | `` | **Callouts:** vox.ai docs use only two kinds, at most two per page (see `guide/components/callouts.md`): * `` - A fact outside the main flow (limits, prerequisites, failure behavior) * `` - Irreversible actions, billing, data deletion ### Reusable content **When to use snippets:** * Exact content appears on more than one page * Complex components you want to maintain in one place * Shared content across teams/repos **When NOT to use snippets:** * Slight variations needed per page (leads to complex props) Import snippets with `import { Component } from "/path/to/snippet-name.jsx"`. ## Document APIs **Choose your approach:** * **Have an OpenAPI spec?** → Add to `docs.json` with `"openapi": ["openapi.yaml"]`. Pages auto-generate. Reference in navigation as `GET /endpoint` * **No spec?** → Write endpoints manually with `api: "POST /users"` in frontmatter. More work but full control * **Hybrid** → Use OpenAPI for most endpoints, manual pages for complex workflows Encourage users to generate endpoint pages from an OpenAPI spec. It is the most efficient and easiest to maintain option. ## Deploy Mintlify deploys automatically when changes are pushed to the connected Git repository. **What agents can configure:** * **Redirects** → Add to `docs.json` with `"redirects": [{"source": "/old", "destination": "/new"}]` * **SEO indexing** → Control with `"seo": {"indexing": "all"}` to include hidden pages in search **Requires dashboard setup (human task):** * Custom domains and subdomains * Preview deployment settings * DNS configuration For `/docs` subpath hosting with Vercel or Cloudflare, agents can help configure rewrite rules. See [/docs subpath](https://mintlify.com/docs/deploy/vercel). ## Edge cases ### Migrations If a user asks about migrating to Mintlify, ask if they are using ReadMe or Docusaurus. If they are, use the [@mintlify/scraping](https://www.npmjs.com/package/@mintlify/scraping) CLI to migrate content. If they are using a different platform to host their documentation, help them manually convert their content to MDX pages using Mintlify components. ### Hidden pages Any page that is not included in the `docs.json` navigation is hidden. Use hidden pages for content that should be accessible by URL or indexed for the assistant or search, but not discoverable through the sidebar navigation. ### Exclude pages The `.mintignore` file is used to exclude files from a documentation repository from being processed. ## Common gotchas 1. **Component imports** - JSX components need explicit import, MDX components don't 2. **Frontmatter required** - Every MDX file needs `title` at minimum 3. **Code block language** - Always specify language identifier 4. **Never use `mint.json`** - `mint.json` is deprecated. Only ever use `docs.json` ## Resources * [Documentation](https://mintlify.com/docs) * [Configuration schema](https://mintlify.com/docs.json) * [Feature requests](https://github.com/orgs/mintlify/discussions/categories/feature-requests) * [Bugs and feedback](https://github.com/orgs/mintlify/discussions/categories/bugs-feedback) # TEST Source: https://docs.tryvox.co/TEST # LLM Agent E2E Test Missions 이 문서는 vox.ai의 LLM-facing 제품(docs, MCP, skills/plugins)이 외부 LLM 에이전트 관점에서 정상 동작하는지 검증하는 E2E 테스트 미션을 정의한다. ## 테스트 원칙 * 테스트 에이전트는 vox.ai 내부 코드를 모른다. 공개된 문서와 도구만 사용한다. * 진입점은 항상 `https://docs.tryvox.co/llms.txt` 이다. * 각 미션은 독립적으로 수행 가능해야 한다. * 실패 지점은 제품(docs/MCP/skills) 중 어디의 문제인지 분류한다. ## 대상 제품 | 제품 | 소스 | 배포 URL | | - | - | - | | Docs | `domains/voxai/docs/` | `https://docs.tryvox.co` | | Skills/Plugin | `domains/voxai/skills/` | `https://github.com/vox-public/vox-skills` | | MCP | `domains/voxai/mcp/` | `https://mcp.tryvox.co/mcp` | ## 참고 문서 Plugin 시스템별 참고 자료는 `_references/` 디렉토리에 있다. | 파일 | 내용 | | - | - | | `_references/claude-code-plugins.md` | Claude Code plugin 구조, 설치, 매니페스트 스키마 | | `_references/codex-plugins.md` | Codex plugin 구조, 마켓플레이스, Claude Code와의 차이 | | `_references/cowork-plugins.md` | Claude Cowork 커넥터 등록, 제약사항 | ## 실행 루프 미션은 한 번 실행으로 끝나지 않는다. 통과할 때까지 아래 루프를 반복한다. ``` ┌─────────────────────────────────────────────────┐ │ 1. 미션 하달 │ │ 오케스트레이터가 에이전트 브리핑을 준비한다 │ │ ↓ │ │ 2. 에이전트 spawn │ │ 격리된 subagent를 생성하고 미션 프롬프트를 전달한다 │ │ ↓ │ │ 3. 실패 보고 수거 │ │ 에이전트가 막힌 지점, 원인, 에러를 수거한다 │ │ ↓ │ │ 4. 원인 분류 → 코드 수정 │ │ Docs / Skills / MCP 중 해당 레포를 수정한다 │ │ ↓ │ │ 5. 배포 │ │ 수정한 레포를 배포한다 │ │ ↓ │ │ 6. 재테스트 │ │ 동일 미션으로 다시 에이전트를 spawn한다 │ │ → 통과하면 종료, 실패하면 3번으로 복귀 │ └─────────────────────────────────────────────────┘ ``` ### 역할 분리 | 역할 | 누구 | 하는 일 | | - | - | - | | **오케스트레이터** | 사람 + 메인 Claude Code 세션 | 미션 하달, 실패 보고 분석, 코드 수정, 배포 판단 | | **테스트 에이전트** | spawn된 subagent | 미션 수행, 막힌 지점 보고. 내부 코드 접근 불가 | ### 실패 보고 형식 ``` ## 실패 보고 ### 도달한 단계 Step N: (단계 이름) ### 막힌 지점 (구체적으로 어떤 행동을 시도했고 어디서 막혔는지) ### 에러 내용 (에러 메시지, HTTP 상태 코드, 도구 응답 등 원문) ### 시도한 우회 (다른 방법을 시도했다면 무엇을, 왜 실패했는지) ### 원인 추정 Docs / Skills / MCP / Infra 중 하나 + 이유 ``` ## develop 환경 프로덕션 배포 전에 develop 기준으로 E2E 테스트를 수행한다. | 제품 | 프로덕션 | develop | | - | - | - | | Docs | `https://docs.tryvox.co` | `mintlify dev` (로컬) | | Skills/Plugin | `main` branch | `main` branch (직접 push) | | MCP | `https://mcp.tryvox.co/mcp` | `https://vox-mcp-develop.fly.dev/mcp` | Plugin 설치 후 MCP URL을 develop(`https://vox-mcp-develop.fly.dev/mcp`)으로 바꿔서 테스트하면 된다. *** ## 실행 Runbook 미션 실행 시 아래 순서를 따른다. 각 미션이 독립적으로 실행 가능하게 유지한다. ### 1. 환경 준비 * **오케스트레이터 세션**: vox-mono 작업 디렉토리의 메인 Claude Code 세션. 세 레포(`docs`, `skills`, `mcp`) 모두에 접근 가능. * **테스트 계정**: vox.ai 테스트 전용 계정 1개(구매/결제 가능 상태). 프로덕션 고객 데이터와 섞이지 않도록 별도 워크스페이스를 쓴다. * **테스트 전화번호**: 수신 가능한 개인 번호 1개. Mission 완료 시 실제 통화가 걸려온다. * **MCP 환경**: 프로덕션은 `https://mcp.tryvox.co/mcp`, develop 검증은 `https://vox-mcp-develop.fly.dev/mcp`. * **세션 격리**: 테스트 에이전트는 vox-mono 소스를 볼 수 없는 상태에서 실행한다. 오케스트레이터 세션의 Agent tool로 새 서브에이전트를 spawn하고, 브리핑에 공개 URL(`https://docs.tryvox.co/llms.txt`)만 제공한다. ### 2. 미션 실행 1. 오케스트레이터가 Mission N 브리핑을 준비하고 `[CLIENT]`, `[TEST_PHONE_NUMBER]` 같은 변수를 치환한다. 2. 서브에이전트를 spawn한다. 경로별로 AI 앱이 달라야 하므로 각 경로는 별도 실행 lane을 사용한다: * 경로 1A(Claude Code): 동일 Claude Code 인스턴스의 subagent * 경로 1B(Codex): 별도 Codex 세션(수동 실행 후 transcript 수집) * 경로 1C(Cowork): Cowork 앱에서 수동 실행 후 transcript 수집 3. 서브에이전트가 최종 보고를 반환하면 오케스트레이터가 기록한다. ### 3. 결과 기록 각 실행 결과는 `domains/voxai/docs/_references/test-runs//-.md`에 남긴다(커밋하지 않을 수도 있음, gitignore 정책은 별도 판단). * 통과 시: 체크리스트 + 각 step의 실제 명령/응답 요약 * 실패 시: "실패 보고" 섹션(도달 단계·막힌 지점·에러·시도한 우회·원인 추정)을 그대로 복사 ### 4. 원인 분류 → 수정 → 재실행 실패 보고의 `원인 추정`을 기준으로 수정 대상 레포를 정한다. 수정 범위가 여러 레포에 걸치면 레포별 별도 커밋으로 처리한다. 동일 미션을 다시 spawn해 통과 여부만 본다. ### 5. Pass/Fail 종합 판정 한 미션의 **모든 경로**가 통과해야 미션이 통과한 것으로 본다. 한 경로만 통과한 상태에서는 미션을 close하지 않는다. *** ## Mission 1: Plugin 설치 → 첫 아웃바운드 콜 ### 목표 LLM 에이전트가 vox.ai 문서를 따라 plugin을 설치하고, 에이전트를 생성한 뒤, 아웃바운드 테스트 콜을 발신하기까지의 전체 온보딩 플로우를 검증한다. ### 온보딩 경로 이 미션은 **3개 클라이언트** 각각에서 성공해야 한다. 각 경로별로 독립적으로 테스트한다. | 경로 | 클라이언트 | plugin 설치 방법 | MCP 등록 방식 | | - | - | - | - | | **1A** | Claude Code | `/plugin marketplace add vox-public/vox-skills` → `/plugin install vox-ai@vox-ai` → `/reload-plugins` | `.mcp.json` 자동 등록 | | **1B** | Codex | `codex marketplace add vox-public/vox-skills` → App `Plugins` 또는 CLI `/plugins`에서 `vox-ai` 설치 | `.mcp.json` 자동 등록 | | **1C** | Claude Cowork | 사용자 지정 → 개인 플러그인 → 마켓플레이스 추가 `vox-public/vox-skills` → 커넥터 메뉴에서 `vox`/`vox-docs` 설치·연결 | `.mcp.json` 자동 등록 | ### 핵심 판정 기준 > **MCP 직접 연결 명령(`claude mcp add ...`)을 실행했다면 실패다.** > > 세 경로 모두 Plugin 설치를 통해 `.mcp.json`이 자동으로 MCP를 등록해야 한다. > 에이전트가 docs에서 `claude mcp add` 명령을 찾아 실행하는 것은 > plugin 온보딩 경로가 아닌 수동 연결이므로 실패로 판정한다. ### 전제조건 | 항목 | 요구사항 | | - | - | | 런타임 | 경로별 클라이언트 (Claude Code / Codex / Cowork) | | 인증 | vox.ai 계정 (OAuth 또는 API 키) | | 전화번호 | 테스트 수신용 전화번호 1개 | | 네트워크 | `docs.tryvox.co`, `mcp.tryvox.co`, `github.com` 접근 가능 | ### 에이전트 브리핑 아래는 테스트 LLM 에이전트에게 전달할 미션 프롬프트다. `[CLIENT]`와 `[TEST_PHONE_NUMBER]`는 실행 시 치환한다. ``` 당신은 vox.ai를 처음 사용하는 개발자입니다. 현재 [CLIENT]를 사용하고 있습니다. 아래 문서를 시작점으로 삼아 음성 에이전트를 만들고 테스트 통화까지 완료하세요. 진입점: https://docs.tryvox.co/llms.txt 목표: 1. vox.ai plugin을 설치하세요. 2. 에이전트를 만들 수 있는 도구(MCP)에 연결되었는지 확인하세요. 3. 간단한 고객 상담 에이전트를 만드세요. 4. 만든 에이전트로 [TEST_PHONE_NUMBER]에 테스트 전화를 거세요. 규칙: - 위 진입점 문서에서 출발하여 필요한 정보를 스스로 찾으세요. - 문서에 없는 정보는 추측하지 마세요. - plugin 설치를 통해 MCP 연결이 자동으로 되는 것이 이상적입니다. - 각 단계를 완료할 때마다 결과를 기록하세요. - 막히는 부분이 있으면 어디서 왜 막혔는지 상세히 기록하세요. 최종 보고: - 모든 단계를 완료했으면 각 단계의 결과를 요약하세요. - 막힌 단계가 있으면 아래 형식으로 보고하세요: ## 실패 보고 ### 도달한 단계 ### 막힌 지점 ### 에러 내용 ### 시도한 우회 ### 원인 추정 (Docs / Skills / MCP / Infra 중 하나 + 이유) ``` ### 검증 단계 #### Step 1: 진입점 접근 | 항목 | 내용 | | - | - | | 행동 | `https://docs.tryvox.co/llms.txt` fetch | | 성공 기준 | 200 응답, 문서 인덱스 수신 | | 실패 → Docs | llms.txt 미배포 또는 경로 오류 | #### Step 2: Plugin 설치 경로별로 기대하는 행동이 다르다. **경로 1A (Claude Code)**: | 항목 | 내용 | | - | - | | 행동 | docs(`/docs/ai/claude-code`)에서 plugin 설치 명령을 찾아 실행 | | 기대 명령 | `/plugin marketplace add vox-public/vox-skills` → `/plugin install vox-ai@vox-ai` → `/reload-plugins` | | 성공 기준 | plugin 설치 완료, `/plugin` 목록에 `vox-ai` 등록, `vox-ai:*` 스킬이 세션에 로드 | | 실패 → Docs | 설치 명령을 문서에서 찾지 못함, 또는 stale 명령(`claude plugin ...` CLI나 `npx skills add`)을 안내 | | 실패 → Skills | GitHub 레포 접근 불가, `.claude-plugin/marketplace.json` 오류, skill 미등록 | **경로 1B (Codex)**: | 항목 | 내용 | | - | - | | 행동 | docs에서 Codex plugin 설치 방법을 찾아 실행 | | 기대 행동 | `/plugins`에서 vox.ai 검색 또는 마켓플레이스 추가 후 설치 | | 성공 기준 | plugin 설치 완료, vox.ai 도구 사용 가능 | | 실패 → Docs | Codex 경로 안내 누락 | | 실패 → Skills | `.codex-plugin/plugin.json` 미제공 또는 구조 오류 | **경로 1C (Cowork)**: | 항목 | 내용 | | - | - | | 행동 | docs에서 Cowork plugin 설치 방법을 찾아 실행 | | 기대 행동 | Cowork 앱 Browse plugins에서 설치 또는 커스텀 plugin 업로드 | | 성공 기준 | plugin 설치 완료, 도구 호출 가능 | | 실패 → Docs | Cowork plugin 설치 안내 누락 또는 불명확 | | 실패 → Skills | plugin 파일 구조 오류, Cowork 호환 문제 | #### Step 3: MCP 자동 등록 확인 | 항목 | 내용 | | - | - | | 행동 | plugin 설치 후 MCP 도구 사용 가능 여부 확인 | | 성공 기준 | `list_agents` 등 vox MCP 도구가 자동으로 사용 가능 | | **자동 실패 조건** | 에이전트가 `claude mcp add` 명령을 실행함 (모든 경로) | | 실패 → Skills | `.mcp.json` 누락 또는 자동 등록 실패 | | 실패 → MCP | 서버 다운, 도구 미노출 | #### Step 4: 에이전트 생성 | 항목 | 내용 | | - | - | | 행동 | `create_agent` MCP 도구 호출 | | 성공 기준 | agent\_id 반환, `get_agent`로 조회 성공 | | 실패 → Skills | onboarding skill의 가이드 부족 | | 실패 → MCP | create\_agent schema 불명확, API 에러 | #### Step 5: 아웃바운드 콜 발신 | 항목 | 내용 | | - | - | | 행동 | `create_call` MCP 도구로 테스트 번호에 전화 발신 | | 성공 기준 | call\_id 반환, 실제 전화 수신 | | 실패 → MCP | 발신 번호 없음 안내 부족, 파라미터 설명 부족 | | 실패 → Infra | SIP/텔레포니 문제 (이 테스트 범위 밖) | ### 실패 원인 분류 | 분류 | 수정 대상 | 배포 방법 | | - | - | - | | **Docs** | `domains/voxai/docs/` | Mintlify 자동 배포 (push to main) | | **Skills** | `domains/voxai/skills/` | GitHub push (vox-public/vox-skills) | | **MCP** | `domains/voxai/mcp/` | Fly.io 배포 | | **Infra** | 범위 밖 | 별도 대응 | ### 경로별 체크리스트 #### 경로 1A: Claude Code ``` [ ] Step 1: llms.txt 접근 — 200 응답 [ ] Step 2: Plugin 설치 — skill 목록에 vox 등록 [ ] Step 3: MCP 자동 등록 — claude mcp add 실행 없이 도구 사용 가능 [ ] Step 4: 에이전트 생성 — agent_id 반환 [ ] Step 5: 아웃바운드 콜 — 전화 수신 ``` #### 경로 1B: Codex ``` [ ] Step 1: llms.txt 접근 — 200 응답 [ ] Step 2: Plugin 설치 — Codex plugin directory에서 설치 성공 [ ] Step 3: MCP 자동 등록 — 수동 설정 없이 도구 사용 가능 [ ] Step 4: 에이전트 생성 — agent_id 반환 [ ] Step 5: 아웃바운드 콜 — 전화 수신 ``` #### 경로 1C: Claude Cowork ``` [ ] Step 1: llms.txt 접근 — 200 응답 [ ] Step 2: Plugin 설치 — Cowork 앱에서 plugin 설치 성공 [ ] Step 3: MCP 자동 등록 — 수동 설정 없이 도구 사용 가능 [ ] Step 4: 에이전트 생성 — agent_id 반환 [ ] Step 5: 아웃바운드 콜 — 전화 수신 ``` *** ## Mission 2: (미정) ## Mission 3: (미정) # 에이전트 메뉴얼 단건 조회 Source: https://docs.tryvox.co/api-reference/v3/agentmanuals/에이전트-메뉴얼-단건-조회 /api-reference/v3/openapi.json get /agents/{agent_id}/manuals/{manual_id} 메뉴얼 1건을 조회합니다. 본문, 빌트인 도구, 참조, 진단을 함께 반환합니다. # 에이전트 메뉴얼 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/agentmanuals/에이전트-메뉴얼-목록-조회 /api-reference/v3/openapi.json get /agents/{agent_id}/manuals 에이전트의 현재 편집본에 있는 메뉴얼 목록을 조회합니다. 목록 항목은 요약 정보이며, 본문과 빌트인 도구는 메뉴얼 단건 조회에서 확인합니다. # 에이전트 메뉴얼 삭제 Source: https://docs.tryvox.co/api-reference/v3/agentmanuals/에이전트-메뉴얼-삭제 /api-reference/v3/openapi.json delete /agents/{agent_id}/manuals/{manual_id} 에이전트의 현재 편집본에서 메뉴얼을 삭제합니다. 삭제 후 리비전은 응답 헤더 `X-Agent-Head-Revision`으로 반환합니다. # 에이전트 메뉴얼 생성 Source: https://docs.tryvox.co/api-reference/v3/agentmanuals/에이전트-메뉴얼-생성 /api-reference/v3/openapi.json post /agents/{agent_id}/manuals 에이전트의 현재 편집본에 메뉴얼을 추가합니다. 추가한 메뉴얼은 다음 에이전트 버전부터 포함됩니다. # 에이전트 메뉴얼 수정 Source: https://docs.tryvox.co/api-reference/v3/agentmanuals/에이전트-메뉴얼-수정 /api-reference/v3/openapi.json patch /agents/{agent_id}/manuals/{manual_id} 에이전트의 현재 편집본에 있는 메뉴얼을 부분 수정합니다. 생략한 필드는 유지되고, 필드에 `null`은 보낼 수 없습니다. # 에이전트 단건 조회 Source: https://docs.tryvox.co/api-reference/v3/agents/에이전트-단건-조회 /api-reference/v3/openapi.json get /agents/{agent_id} 에이전트 1건을 조회합니다. `version=current`는 수정 가능한 현재 상태를, `production`이나 `v{n}`은 저장된 스냅샷을 반환합니다. # 에이전트 목록 Source: https://docs.tryvox.co/api-reference/v3/agents/에이전트-목록 /api-reference/v3/openapi.json get /agents 인증된 워크스페이스(`organization_id`)의 에이전트 목록을 조회합니다. 목록 항목은 요약 정보이며, `data`, `flow_data`, 버전 스냅샷은 단건 조회에서 확인합니다. # 에이전트 삭제 Source: https://docs.tryvox.co/api-reference/v3/agents/에이전트-삭제 /api-reference/v3/openapi.json delete /agents/{agent_id} 인증된 워크스페이스(`organization_id`)의 에이전트를 삭제 처리합니다. # 에이전트 생성 Source: https://docs.tryvox.co/api-reference/v3/agents/에이전트-생성 /api-reference/v3/openapi.json post /agents single-prompt 또는 flow 에이전트를 생성합니다. flow 에이전트는 권장 경로인 `flow` 필드(`{nodes, edges}`)로 그래프를 작성하고, 기존 `flow_data`는 호환용입니다. # 에이전트 수정 Source: https://docs.tryvox.co/api-reference/v3/agents/에이전트-수정 /api-reference/v3/openapi.json patch /agents/{agent_id} 에이전트를 부분 수정합니다. 생략한 필드는 유지되고, `type`은 변경할 수 없습니다. flow 그래프는 `flow` 필드로 작성하며 전체 교체로 동작합니다(현재 그래프를 유지하려면 생략). 기존 `flow_data`는 호환용입니다. # 플로우 검증 Source: https://docs.tryvox.co/api-reference/v3/agents/플로우-검증 /api-reference/v3/openapi.json post /agents/validate-flow `flow`(`{nodes, edges}`)를 저장하지 않고 검증합니다. `valid`는 저장 가능 여부를 나타내며, 저장을 막는 치명적 오류가 없으면 `true`입니다. 런타임 주의 항목은 `valid`에 영향을 주지 않습니다. `?agent_id`를 주면 해당 에이전트의 현재 `flow`를 기준으로 수정(PATCH) 시 적용되는 참조 검사(orphan·dangling·multifanout)까지 포함합니다. `?level`로 응답에 포함할 항목 범주(`critical`/`runtime`/`all`)를 정합니다. 런타임 주의 항목(저장은 가능하지만 실행 중 동작이 달라질 수 있음): - `unconnected_skip_user_response_transition`: skip/wakeup 전환 행에 나가는 전환이 없습니다. - `unconnected_fallback_transition`: fallback 전환 행에 나가는 전환이 없습니다. - `no_terminal_reachable`: begin 노드에서 도달 가능한 종료 노드(endCall / transferCall / transferAgent)가 없습니다. # 에이전트 버전 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/agentversions/에이전트-버전-목록-조회 /api-reference/v3/openapi.json get /agents/{agent_id}/versions 에이전트의 저장된 버전 목록을 조회합니다. 응답에는 버전 메타데이터만 포함되며, 스냅샷 본문은 에이전트 단건 조회에서 `version=v{n}`으로 확인합니다. # 에이전트 버전 생성 Source: https://docs.tryvox.co/api-reference/v3/agentversions/에이전트-버전-생성 /api-reference/v3/openapi.json post /agents/{agent_id}/versions 에이전트의 현재 `data`와 `flow_data`를 변경 불가능한 버전으로 저장합니다. # 에이전트 버전 프로덕션 게시 Source: https://docs.tryvox.co/api-reference/v3/agentversions/에이전트-버전-프로덕션-게시 /api-reference/v3/openapi.json post /agents/{agent_id}/versions/{version}/publish 기존 버전을 production 버전으로 지정합니다. 이후 `agent_version=production`으로 실행되는 통화는 이 스냅샷을 사용합니다. # 알림 규칙 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-목록-조회 /api-reference/v3/openapi.json get /alert-rules 인증된 워크스페이스(`organization_id`)의 알림 규칙 목록을 조회합니다. 현재 동작 상태는 각 항목의 `status`, `enabled`, `paused_until` 필드를 확인합니다. # 알림 규칙 비활성화 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-비활성화 /api-reference/v3/openapi.json post /alert-rules/{alert_rule_id}/disable 설정이나 incident 이력을 삭제하지 않고 알림 규칙을 비활성화합니다. # 알림 규칙 삭제 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-삭제 /api-reference/v3/openapi.json delete /alert-rules/{alert_rule_id} 알림 규칙을 삭제합니다. 이 규칙에 기록된 인시던트와 알림 이력은 유지됩니다. # 알림 규칙 상세 조회 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-상세-조회 /api-reference/v3/openapi.json get /alert-rules/{alert_rule_id} 알림 규칙 1건을 조회합니다. 조건, 채널, 스케줄, 현재 상태를 함께 반환합니다. # 알림 규칙 생성 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-생성 /api-reference/v3/openapi.json post /alert-rules 워크스페이스(`organization_id`) 단위 모니터링을 위한 알림 규칙을 생성합니다. 규칙에는 메트릭 조건, 알림 채널, 활성 스케줄, 활성화 상태가 포함됩니다. # 알림 규칙 수정 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-수정 /api-reference/v3/openapi.json patch /alert-rules/{alert_rule_id} 알림 규칙의 수정 가능한 메타데이터를 변경합니다. 현재는 `name`과 `description`을 수정할 수 있습니다. # 알림 규칙 스케줄 수정 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-스케줄-수정 /api-reference/v3/openapi.json patch /alert-rules/{alert_rule_id}/schedule 알림 규칙이 알림을 보낼 활성 시간대를 수정합니다. # 알림 규칙 인시던트 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-인시던트-목록-조회 /api-reference/v3/openapi.json get /alert-rules/{alert_rule_id}/incidents 특정 알림 규칙에서 발생한 incident 목록을 조회합니다. incident 상태로 필터링할 수 있습니다. # 알림 규칙 일시정지 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-일시정지 /api-reference/v3/openapi.json post /alert-rules/{alert_rule_id}/pause 알림 규칙의 알림 전송을 일시정지합니다. 재개 시각을 함께 지정할 수 있습니다. # 알림 규칙 일시정지 해제 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-일시정지-해제 /api-reference/v3/openapi.json post /alert-rules/{alert_rule_id}/resume 알림 규칙의 일시정지 상태를 해제하고 다시 알림을 보낼 수 있게 합니다. # 알림 규칙 조건 수정 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-조건-수정 /api-reference/v3/openapi.json patch /alert-rules/{alert_rule_id}/condition 알림 조건의 임계값, 비교 방식, 시간 창, label을 수정합니다. # 알림 규칙 채널 수정 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-채널-수정 /api-reference/v3/openapi.json patch /alert-rules/{alert_rule_id}/channels 알림 규칙에서 사용할 알림 채널을 전체 교체합니다. # 알림 규칙 테스트 알림 발송 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-테스트-알림-발송 /api-reference/v3/openapi.json post /alert-rules/{alert_rule_id}/test-notification incident를 만들지 않고 규칙에 설정된 채널로 테스트 알림을 보냅니다. # 알림 규칙 활성화 Source: https://docs.tryvox.co/api-reference/v3/alerts/알림-규칙-활성화 /api-reference/v3/openapi.json post /alert-rules/{alert_rule_id}/enable 조건에 맞는 incident가 알림을 보낼 수 있도록 알림 규칙을 활성화합니다. # 차단 번호 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/blocked-numbers/차단-번호-목록-조회 /api-reference/v3/openapi.json get /blocked-numbers 인증된 워크스페이스(`organization_id`)의 차단 번호 규칙 목록을 조회합니다. 적용 범위, 차단 방향, 활성 상태, 검색 필터로 페이지 결과를 좁힐 수 있습니다. # 차단 번호 삭제 Source: https://docs.tryvox.co/api-reference/v3/blocked-numbers/차단-번호-삭제 /api-reference/v3/openapi.json delete /blocked-numbers/{blocked_number_id} 인증된 워크스페이스(`organization_id`)의 차단 번호 규칙을 삭제합니다. # 차단 번호 생성 Source: https://docs.tryvox.co/api-reference/v3/blocked-numbers/차단-번호-생성 /api-reference/v3/openapi.json post /blocked-numbers 인증된 워크스페이스(`organization_id`)에 차단 번호 규칙을 생성합니다. 규칙을 특정 번호에서만 적용하려면 `specific` 적용 범위에 적용 번호(`specific_numbers`)를 함께 지정합니다. # 차단 번호 수정 Source: https://docs.tryvox.co/api-reference/v3/blocked-numbers/차단-번호-수정 /api-reference/v3/openapi.json patch /blocked-numbers/{blocked_number_id} 차단 번호 규칙의 일부 필드를 수정합니다. 생략한 필드는 유지되고, `memo`처럼 null을 허용하는 필드는 null로 보내 비울 수 있습니다. # 차단 번호 일괄 생성 Source: https://docs.tryvox.co/api-reference/v3/blocked-numbers/차단-번호-일괄-생성 /api-reference/v3/openapi.json post /blocked-numbers/bulk 한 요청으로 차단 번호 규칙을 최대 500건까지 생성합니다. 각 번호는 독립적으로 처리되며, 실패 항목은 성공 항목을 되돌리지 않고 `results`에 보고됩니다. 중복 규칙은 `skipped`로 반환되며, 기존 규칙 교체는 지원하지 않습니다. # 진행 중 통화 전환 요청 Source: https://docs.tryvox.co/api-reference/v3/calls/진행-중-통화-전환-요청 /api-reference/v3/openapi.json post /calls/{call_id}/transfer 진행 중인 전화 통화에 즉시 전환 (cold) 또는 안내 후 전환 (warm)을 요청합니다. 전환 대상은 전화번호 또는 SIP URI로 지정할 수 있습니다. 202 응답은 서버가 보낸 전환 명령이 진행 중인 통화에 전달되어 수락되었다는 뜻입니다. 실제 전환 완료나 전환 대상의 응답을 뜻하지 않습니다. # 통화 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/calls/통화-목록-조회 /api-reference/v3/openapi.json get /calls 인증된 워크스페이스(`organization_id`)의 통화 목록을 조회합니다. 에이전트, 통화 상태, 통화 유형, 전화번호, 종료 사유, 시작 시각, 통화 시간, 에이전트 버전, 메타데이터, 동적 변수로 필터링할 수 있습니다. # 통화 생성 Source: https://docs.tryvox.co/api-reference/v3/calls/통화-생성 /api-reference/v3/openapi.json post /calls 아웃바운드 통화를 생성합니다. 발신번호에 활성 traffic split 정책이 없을 때만 `agent`를 직접 지정할 수 있습니다. # 통화 조회 Source: https://docs.tryvox.co/api-reference/v3/calls/통화-조회 /api-reference/v3/openapi.json get /calls/{call_id} 인증된 워크스페이스(`organization_id`)의 통화 1건을 조회합니다. # 대량 발신 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-목록-조회 /api-reference/v3/openapi.json get /campaigns 인증된 워크스페이스(`organization_id`)의 대량 발신(`campaign`) 목록을 조회합니다. 상태, 에이전트, 생성 시각으로 필터링할 수 있습니다. # 대량 발신 생성 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-생성 /api-reference/v3/openapi.json post /campaigns 하나의 에이전트와 발신번호로 여러 수신자에게 전화를 거는 대량 발신(`campaign`)을 생성합니다. # 대량 발신 수정 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-수정 /api-reference/v3/openapi.json patch /campaigns/{campaign_id} 대량 발신(`campaign`) 이름과 통화 가능 시간대처럼 수정 가능한 설정을 변경합니다. # 대량 발신 일시정지 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-일시정지 /api-reference/v3/openapi.json post /campaigns/{campaign_id}/pause task를 삭제하지 않고 진행 중이거나 예약된 대량 발신(`campaign`)을 일시정지합니다. # 대량 발신 재개 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-재개 /api-reference/v3/openapi.json post /campaigns/{campaign_id}/resume 일시정지된 대량 발신(`campaign`)을 재개해 남은 task를 계속 진행합니다. # 대량 발신 조회 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-조회 /api-reference/v3/openapi.json get /campaigns/{campaign_id} 인증된 워크스페이스(`organization_id`)의 대량 발신(`campaign`) 1건을 조회합니다. # 대량 발신 취소 Source: https://docs.tryvox.co/api-reference/v3/campaigns/대량-발신-취소 /api-reference/v3/openapi.json post /campaigns/{campaign_id}/cancel 대량 발신(`campaign`)을 취소하고 아직 대기 중인 발신 task를 중단합니다. # 네이버톡톡 응대권 전환 Source: https://docs.tryvox.co/api-reference/v3/chats/네이버톡톡-응대권-전환 /api-reference/v3/openapi.json post /chats/{chat_id}/navertalk/handover 네이버 응대권 전환을 요청하고 저장된 처리 결과를 반환합니다. API 키를 쓰는 에이전트 도구는 `X-Vox-Chat-Turn-Id`와 도구마다 고정한 `Idempotency-Key`를 지정해 `external`로 전환할 수 있습니다. AI 복구(`target=ai`)에는 대시보드 로그인 인증(Supabase JWT)이나 내부 관리자 인증이 필요합니다. 결과가 `unknown`이면 자동으로 다시 보내지 않으며, 같은 키로 다시 요청하면 기존 결과를 돌려줍니다. # 네이버톡톡 응대권 조회 Source: https://docs.tryvox.co/api-reference/v3/chats/네이버톡톡-응대권-조회 /api-reference/v3/openapi.json get /chats/{chat_id}/navertalk 저장된 네이버 응대권과 마지막 전환 요청 결과를 조회합니다. 이 요청은 네이버에 상태를 묻지 않으며, 전환 요청을 만들거나 재시도하지도 않습니다. 응대권이 `unknown`이면 AI가 답하지 않습니다. 대시보드 사용자는 연동이 활성이고 대화가 진행 중이며 스팸이 아닐 때 복구를 직접 요청할 수 있습니다. # 채팅 메시지 전송 Source: https://docs.tryvox.co/api-reference/v3/chats/채팅-메시지-전송 /api-reference/v3/openapi.json post /chats/{chat_id}/messages API 채팅에 사용자 메시지를 보냅니다. 에이전트가 응답하면 저장된 결과를 순서대로 반환합니다. 위젯·SMS·카카오의 사용자 입력은 각 채널에서 받습니다. 같은 채팅에 같은 `client_idempotency_key`를 다시 보내면 에이전트를 재실행하지 않고 저장된 결과를 반환합니다. # 채팅 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/chats/채팅-목록-조회 /api-reference/v3/openapi.json get /chats 인증한 워크스페이스의 채팅 목록을 조회합니다. 에이전트, 고객, 채널, 상태, 시작 시각으로 필터링합니다. 목록에는 대화록이 포함되지 않습니다. # 채팅 발신 메시지 전송 Source: https://docs.tryvox.co/api-reference/v3/chats/채팅-발신-메시지-전송 /api-reference/v3/openapi.json post /chats/{chat_id}/outbound-messages 에이전트를 실행하지 않고 채팅 메시지 한 건을 만든 뒤, 채널이 지원하면 그 채널로 보냅니다. `origin=human`은 Supabase JWT와 `X-Vox-Organization-Id` 헤더가 필요하며, 호출자가 활성 상담사이면서 이 채팅을 지금 응대 중이어야 합니다. `origin=system`은 워크스페이스 API 키나 내부 관리자 인증이 필요합니다. # 채팅 생성 Source: https://docs.tryvox.co/api-reference/v3/chats/채팅-생성 /api-reference/v3/openapi.json post /chats 프롬프트 또는 플로우 에이전트로 API 채팅을 생성합니다. 저장된 첫 대화 내역을 함께 반환합니다. # 채팅 조회 Source: https://docs.tryvox.co/api-reference/v3/chats/채팅-조회 /api-reference/v3/openapi.json get /chats/{chat_id} 채팅 한 건과 전체 대화록을 조회합니다. 대화록은 메시지 순서대로 반환합니다. # 채팅 종료 Source: https://docs.tryvox.co/api-reference/v3/chats/채팅-종료 /api-reference/v3/openapi.json post /chats/{chat_id}/end 채팅을 종료합니다. 종료 후에는 새 메시지를 보낼 수 없습니다. 이미 종료된 채팅에도 본문 없이 204를 반환합니다. # 고객 속성 정의 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/customer-attribute-definitions/고객-속성-정의-목록-조회 /api-reference/v3/openapi.json get /customer-attribute-definitions 인증된 워크스페이스(`organization_id`)의 고객 속성 정의 목록을 조회합니다. # 고객 속성 정의 삭제 Source: https://docs.tryvox.co/api-reference/v3/customer-attribute-definitions/고객-속성-정의-삭제 /api-reference/v3/openapi.json delete /customer-attribute-definitions/{definition_id} 고객 속성 정의를 영구 삭제합니다. 고객의 `attributes`에 저장된 기존 값은 유지되지만 더 이상 속성 정의와 연결되지 않습니다. # 고객 속성 정의 생성 Source: https://docs.tryvox.co/api-reference/v3/customer-attribute-definitions/고객-속성-정의-생성 /api-reference/v3/openapi.json post /customer-attribute-definitions 인증된 워크스페이스(`organization_id`)에 고객 속성 정의를 생성합니다. 속성 키는 워크스페이스 안에서 고유해야 합니다. # 고객 속성 정의 수정 Source: https://docs.tryvox.co/api-reference/v3/customer-attribute-definitions/고객-속성-정의-수정 /api-reference/v3/openapi.json patch /customer-attribute-definitions/{definition_id} 인증된 워크스페이스(`organization_id`)의 고객 속성 정의를 수정합니다. 생략한 필드는 유지합니다. # 고객 속성 정의 조회 Source: https://docs.tryvox.co/api-reference/v3/customer-attribute-definitions/고객-속성-정의-조회 /api-reference/v3/openapi.json get /customer-attribute-definitions/{definition_id} 인증된 워크스페이스(`organization_id`)의 고객 속성 정의 하나를 조회합니다. # 고객 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/customers/고객-목록-조회 /api-reference/v3/openapi.json get /customers 인증된 워크스페이스(`organization_id`)의 고객 목록을 생성 시각 내림차순으로 조회합니다. `q`는 고객 이름과 식별자 값에서 대소문자 구분 없이 일부 일치 항목을 찾습니다. 메모는 검색하지 않습니다. 목록에는 `metadata`와 `interaction_summary`가 없습니다. 전체 프로필과 인터랙션 요약은 고객 단건 조회에서 확인합니다. # 고객 삭제 Source: https://docs.tryvox.co/api-reference/v3/customers/고객-삭제 /api-reference/v3/openapi.json delete /customers/{customer_id} 인증된 워크스페이스의 고객을 영구 삭제합니다. 식별자, 상담사 메모(답글·반응 포함), 상태·담당자 이력과 메모리도 함께 삭제합니다. 연결된 통화와 채팅의 `customer_id`는 null로 바꾸고 대화 기록은 유지합니다. 다른 워크스페이스의 ID는 404 `CUSTOMER_NOT_FOUND`를 반환합니다. # 고객 생성 Source: https://docs.tryvox.co/api-reference/v3/customers/고객-생성 /api-reference/v3/openapi.json post /customers 인증된 워크스페이스(`organization_id`)에 고객을 생성합니다. 식별자가 하나 이상 필요합니다. 식별자 값은 유형에 맞게 정규화됩니다. 값이 올바르지 않으면 400 `VALIDATION_ERROR`를 반환합니다. 같은 `(type, value)`를 이미 사용 중이면 409 `CUSTOMER_IDENTIFIER_EXISTS`를 반환하며 고객을 생성하지 않습니다. 중복 고객은 생성 후 병합할 수 있습니다. # 고객 수정 Source: https://docs.tryvox.co/api-reference/v3/customers/고객-수정 /api-reference/v3/openapi.json patch /customers/{customer_id} 인증된 워크스페이스(`organization_id`)의 고객 정보를 수정합니다. 생략한 필드는 유지합니다. `metadata`는 최상위 키를 추가하거나 교체하며 기존 키를 삭제하지 않습니다. `identifiers`에 담은 식별자는 고객에게 추가됩니다. 기존 식별자 값은 수정하거나 삭제하지 않습니다. 식별자 하나라도 사용 중이면 전체 요청이 409 `CUSTOMER_IDENTIFIER_EXISTS`로 실패합니다. 다른 워크스페이스의 고객 ID는 404 `CUSTOMER_NOT_FOUND`로 처리합니다. # 고객 식별자 삭제 Source: https://docs.tryvox.co/api-reference/v3/customers/고객-식별자-삭제 /api-reference/v3/openapi.json delete /customers/{customer_id}/identifiers/{identifier_id} 인증된 워크스페이스(`organization_id`)의 고객에서 식별자 하나를 삭제합니다. 마지막 식별자는 삭제할 수 없으며 409 `CUSTOMER_LAST_IDENTIFIER`를 반환합니다. 식별자가 없거나 다른 워크스페이스에 속하면 404 `CUSTOMER_NOT_FOUND`를 반환합니다. # 고객 조회 Source: https://docs.tryvox.co/api-reference/v3/customers/고객-조회 /api-reference/v3/openapi.json get /customers/{customer_id} 인증된 워크스페이스(`organization_id`)의 고객 한 명을 조회합니다. 프로필, 식별자, 인터랙션 요약과 에이전트별 활성 메모리를 반환합니다. 메모리는 고객 단건 조회에만 포함됩니다. 목록, 식별자 검색, 생성, 수정, 병합 응답에는 포함되지 않습니다. 다른 워크스페이스의 고객 ID는 404 `CUSTOMER_NOT_FOUND`로 처리합니다. # 식별자로 고객 조회 Source: https://docs.tryvox.co/api-reference/v3/customers/식별자로-고객-조회 /api-reference/v3/openapi.json get /customers/find 인증된 워크스페이스(`organization_id`)에서 식별자로 고객 한 명을 찾습니다. 전화번호는 한국 표준 형식으로 정규화하고, 이메일은 소문자로 바꾸며, 그 밖의 식별자 값은 앞뒤 공백을 제거한 뒤 검색합니다. `identifier_type`을 지정하면 해당 유형만 검색합니다. 생략하면 `phone`, `email`, `external_id` 순서로 검색해 처음 일치한 고객을 반환합니다. 일치하는 고객이 없으면 404 `CUSTOMER_NOT_FOUND`를 반환합니다. # 식별자로 고객 조회 또는 생성 Source: https://docs.tryvox.co/api-reference/v3/customers/식별자로-고객-조회-또는-생성 /api-reference/v3/openapi.json post /customers/resolve 인증된 워크스페이스(`organization_id`)에서 전화번호, 이메일, 외부 ID 중 하나 이상으로 고객 한 명을 찾거나 만듭니다. 식별자는 인터랙션 귀속과 같은 표준 정규화와 우선순위를 사용합니다. 우선순위는 `external_id`, 전화번호, 이메일 순입니다. 같은 워크스페이스 범위 식별자에 대해 원자적이고 멱등하게 동작합니다. # 중복 고객 병합 Source: https://docs.tryvox.co/api-reference/v3/customers/중복-고객-병합 /api-reference/v3/openapi.json post /customers/merge 인증된 워크스페이스의 중복 고객을 대표 고객으로 병합합니다. 중복 고객의 식별자, 통화, 상담사 통화, 채팅, 발신·수신 SMS, 메모리, 대기 중인 메모리 이벤트, 상담사 메모(답글·반응 포함), 상태·담당자 이력을 대표 고객으로 옮기고 중복 고객을 영구 삭제합니다. 충돌 시 대표 고객의 프로필을 우선하지만, 이름·메모가 비어 있거나 속성 값이 없으면 중복 고객의 값으로 채웁니다. 병합 후 메모리 저장 한도를 다시 적용합니다. `main_customer_id`와 `duplicate_customer_id`는 달라야 하며, 같으면 400 `INVALID_MERGE`를 반환합니다. 두 고객 모두 워크스페이스에 존재해야 하며, 아니면 404 `CUSTOMER_NOT_FOUND`를 반환합니다. 전체 작업은 하나의 트랜잭션으로 실행하며 실패하면 모두 되돌립니다. # 파일 다운로드 Source: https://docs.tryvox.co/api-reference/v3/files/파일-다운로드 /api-reference/v3/openapi.json get /files/{file_key}/content 워크스페이스(`organization_id`)가 소유한 `file_key`의 저장된 파일 바이트를 다운로드합니다. `sms_received` 웹훅 페이로드나 대화 메시지 `attachments`에 담긴 수신 MMS 첨부, 발급된 통신서비스 이용증명원 PDF를 받을 때 사용합니다. `Authorization: Bearer `을 보내세요. 응답 본문은 저장된 MIME 타입(`image/jpeg`, `image/png`, `image/gif`, `application/pdf`)으로 제공되는 원본 바이트입니다. `file_key`는 불투명한 고유 키(`file_`)이며 연결된 바이트는 변하지 않습니다. 응답에는 `ETag`와 immutable `Cache-Control`이 포함되고, `If-None-Match` 조건부 요청은 다시 내려받지 않고 `304 Not Modified`를 반환합니다. 존재하지 않는 `file_key`와 다른 워크스페이스 소유의 `file_key`는 동일한 `404`를 반환합니다. # 파일 업로드 Source: https://docs.tryvox.co/api-reference/v3/files/파일-업로드 /api-reference/v3/openapi.json post /files MMS 이미지 첨부 파일을 `multipart/form-data`로 업로드하고 `file_key`를 받습니다. 받은 `file_key`는 SMS/MMS 발송 페이로드에서 사용합니다. 동일한 byte를 다시 업로드하면 같은 `file_key`가 반환됩니다. # 인시던트 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/incidents/인시던트-목록-조회 /api-reference/v3/openapi.json get /incidents 인증된 워크스페이스(`organization_id`)의 모든 알림 규칙에서 발생한 incident 목록을 조회합니다. # 소개 Source: https://docs.tryvox.co/api-reference/v3/introduction vox.ai v3 API로 에이전트, 모델, 도구, 통화, 채팅과 고객 데이터를 관리할 수 있어요. vox.ai v3 API는 음성·채팅 AI 에이전트의 전체 라이프사이클을 코드로 다루는 REST API예요. v2보다 컨벤션이 일관되고 에러 모델이 명시적이며, 스키마 레지스트리와 OpenAPI로 지금 계약을 직접 확인할 수 있어요. ## Base URL ``` https://client-api.tryvox.co/v3 ``` ## 인증 모든 요청에 `Authorization: Bearer ` 헤더가 필요해요. 토큰은 [대시보드 설정](https://www.tryvox.co/dashboard/)에서 발급한 워크스페이스(`organization_id`) API 키를 쓰세요. ```bash theme={null} curl https://client-api.tryvox.co/v3/agents \ -H "Authorization: Bearer $VOX_API_KEY" ``` ## 컨벤션 * **snake\_case**: 요청·응답 필드는 기본으로 snake\_case를 써요. `agent.data`와 `flow.nodes[].data` 아래는 에이전트 설정과 노드별 설정을 그대로 담으려고 일부 camelCase를 유지해요. * **플로우 작성과 검증**: 플로우 에이전트 그래프는 `flow` 필드로 작성하고, 저장하기 전에 `POST /agents/validate-flow`로 검증할 수 있어요. `flow_data`는 기존 빌더 호환용 필드라 새 통합에서는 쓰지 않는 편이 좋아요. 작성법은 [API로 플로우 작성 및 검증](/docs/build/flow/api-authoring)에 있어요. * **밀리초 타임스탬프**: `_at`으로 끝나는 타임스탬프 필드는 unix milliseconds예요. * **커서 페이지네이션**: list 엔드포인트는 `cursor`와 `limit`(1\~100)을 써요. 다음 페이지는 응답의 `next_cursor`를 그대로 다시 넘기세요. * **명시적 식별자**: 응답 객체 자신의 ID는 `id`예요. 다른 리소스 참조는 `agent_id`, `call_id`처럼 이름을 밝혀 써요. * **에러 엔벨로프**: 모든 실패 응답은 `{ "error": { "code", "message", "details" } }` 꼴이에요. 제어 흐름은 `code`로 나누세요. * **Rate limit**: 모든 v3 엔드포인트는 워크스페이스 단위 rate limit(초당 5회, 분당 120회)을 함께 써요. 넘으면 `429`와 `RATE_LIMIT_EXCEEDED` 코드를 돌려줘요. * **음성 런타임**: 새로 만들 때 `agent.data.runtime`을 생략하거나 `{ "type": "pipeline" }`으로 보내면 기존 파이프라인을 써요. 수정할 때 `runtime`을 생략하면 지금 런타임을 유지해요. GPT-Live, Grok Voice, Gemini Live는 지금 `type: "single_prompt"`에서만 지원하고 플로우 에이전트에서는 거부돼요. 작성 규칙은 [실시간 음성 런타임 API 작성](/docs/build/single-prompt/gpt-live)에 있어요. * **대시보드 용어 대응**: 대시보드의 **대량 발신**은 API에서 `campaign`이고, **문자 대량 발신**은 `sms_batch`예요. 경로·필드·이벤트 이름은 영문 그대로 써요. ## 주요 리소스 * **에이전트**: 음성 에이전트(single prompt, flow)와 버전을 만들고 수정하고 게시해요. * **모델**: 에이전트에 쓸 수 있는 LLM과 음성 모델을 조회하고 관리해요. * **도구**: 에이전트가 호출할 API 도구를 만들고 실행 설정을 관리해요. * **지식 베이스**: 에이전트가 참조할 지식 베이스와 원본 문서를 관리해요. * **스키마**: `agent.data`, 플로우와 도구의 공개 JSON Schema를 조회해요. * **전화번호**: 번호 구매·등록, 에이전트 매핑, SIP 트렁크를 관리해요. * **통화·대량 발신·SMS**: 통화 한 건과 대량 발신(`campaign`)을 실행하고 조회해요. SMS는 발신·수신 목록과 단건 상세를 조회해요. * **채팅**: 채팅을 만들고 메시지를 보내요. 대화 내역을 조회하고 상담을 끝내요. 연동 절차는 [API 채팅](/docs/operate/deploy/chat-api)에 있어요. * **고객·메모리**: 고객 식별자와 고객 속성, 대화에서 추출한 메모리를 관리해요. * **알림**: 통화 지표를 감시할 알림 규칙과 인시던트를 관리해요. ## 스키마 레지스트리 v3는 에이전트 작성에 필요한 JSON Schema를 API와 OpenAPI로 열어 둬요. 클라이언트는 스키마를 하드코딩하지 않고 지금 계약을 확인해 쓸 수 있어요. * `GET /schemas`: 쓸 수 있는 스키마 목록(`agent-schema`, `flow-schema`, `tool-schema` 등)을 조회해요. * `GET /schemas/{namespace}/{schema_type}`: 특정 스키마 본문을 조회해요. * `GET /schemas?category=agent-authoring&include_schema=true`: 에이전트 작성에 필요한 레지스트리 스키마를 함께 조회해요. ### 에이전트 data 수정 `PATCH /agents/{agent_id}`에는 `GET /agents/{agent_id}?version=current`에서 확인한 `head_revision`을 `expected_head_revision`으로 넘기세요. 플로우 그래프를 바꿀 때는 같은 응답의 `flow_revision`도 `expected_flow_revision`으로 보내세요. 오래된 revision은 `REVISION_CONFLICT`로 거부되니, 클라이언트가 최신 상태를 자동으로 다시 읽어 그대로 재시도(blind retry)하지 않게 하세요. `data`는 부분 수정 payload예요. 생략한 하위 설정은 기존 값을 유지하고, 일반 객체는 한 단계 병합하며 배열은 통째로 바꿔요. `data.runtime`, `data.manuals`, `data.presetDynamicVariables`는 원자적으로 통째로 바꿔요. `data.builtInTools`를 넣으면 기본 도구 배열도 통째로 바꿔요. * `builtInTools` 생략: 기존 기본 도구 유지 * `builtInTools: []`: 기본 도구 전체 제거 * `builtInTools: null`: 잘못된 요청 * `runtime` 생략: 지금 런타임 유지 * `runtime` 전송: 런타임 객체 전체 교체 * `manuals` 전송: 에이전트 소유 메뉴얼 맵 전체 교체 전역 `/manuals` API는 없어요. 메뉴얼을 읽거나 고치려면 `/agents/{agent_id}/manuals` 하위 경로를 쓰세요. 아래처럼 기본값이 아닌 tool-level 설정은 기존 도구 객체에서 유지해야 해요. | 도구 | 유지할 대표 필드 | | - | - | | 공통 | `speakDuringExecution`, `allowInterruptionDuringExecution`, `responseMode` | | `transfer_call` | `transferConfigurations`, `transferType`, `displayedCallerId`, `transferMessageType`, `warmTransferPrompt`, `warmTransferStaticSentence`, `sipHeaders` | | `transfer_agent` | `agent`, `preserveChatContext` | | `send_sms` | `smsMessageType`, `smsMessagePrompt`, `smsMessageStaticSentence`, `smsMessageStaticTitle`, `smsMessageStaticImageFileKeys`, `smsFromNumber` | | `send_dtmf` | `speakDuringExecution`, `allowInterruption` 또는 `allowInterruptionDuringExecution`, `responseMode` | | `skill` | `skill.skills[]`, `skill.initSkillId`, `skill.initSkillName` | 프롬프트만 바꿀 때는 `builtInTools`를 보내지 않거나, `GET /agents/{agent_id}`에서 받은 도구 객체를 그대로 두고 필요한 필드만 바꾸세요. 정확한 필드 구조는 `GET /schemas/tool-schema/{schema_type}`로 확인하세요. ### 네이티브 실시간 런타임 GPT-Live, Grok Voice, Gemini Live의 음성 설정은 `data.runtime.voice`에 둬요. 기존 파이프라인의 `data.voice`·`data.stt`·`data.parallelSTT`와 현재 스키마에서 호환되지 않는 speech preference를 네이티브 실시간 요청에 복사하지 마세요. `data.speech` 전체를 짐작으로 지우지 말고 현재 agent schema를 따르세요. 새 네이티브 실시간 에이전트를 만들 때는 고를 수 있는 `data.llm.model`이 필요하고, `chatLlm` 필드나 `data.llm`의 암묵적인 모델 매핑은 쓰지 않아요. GPT-Live, Grok Voice, Gemini Live는 유효한 `data.speech.isAllowInterruption` 값이 `true`여야 해요. 만들 때 값을 생략하면 기본값 `true`를 쓰지만, PATCH에서 생략하면 지금 값을 유지해요. 그래서 기존 값이 `false`인 에이전트를 전환할 때는 `true`를 명시하세요. API는 이 값을 자동으로 바꾸지 않아요. 세 런타임은 `type: "single_prompt"` 전용이에요. 기존 `type: "flow"` 에이전트는 `pipeline` 런타임을 쓰고, 자동으로 변환하거나 마이그레이션하지 않아요. `flow.nodes[].data.llm`은 기존 플로우 설정으로 보존하지만 네이티브 실시간 기능으로 해석하지 않아요. 새 에이전트를 만들 때 `data.runtime`을 생략하거나 `type: "pipeline"`으로 보내면 기존 파이프라인 동작을 써요. PATCH에서 `runtime`을 생략하면 지금 런타임을 유지해요. 파이프라인으로 되돌릴 때는 `runtime: { "type": "pipeline" }`과 함께 `stt`, `voice`를 명시하세요. 세 네이티브 실시간 런타임은 provider 전용 model과 음성을 명시해야 해요. GPT-Live는 빌트인이나 커스텀 음성을, Grok Voice와 Gemini Live는 빌트인 음성만 받아요. Grok Voice는 `grok-voice-think-fast-2.0`, Gemini Live는 초기 1.8.1 호환 계약의 `gemini-2.5-flash-native-audio-preview-12-2025`를 써요. Gemini 3.1과 3.8은 지원하지 않아요. Grok Voice와 Gemini Live는 `custom` 음성을 거부해요. `custom` 참조는 새 GPT-Live 커스텀 음성에만 쓰고, 기존 pipeline 음성은 그대로 유지해요. GPT-Live custom reference만으로 OpenAI 권한·프로비저닝이나 품질 검증을 마친 것은 아니에요. ## 관련 문서 * [전화](/docs/operate/outbound/call): API로 통화 한 건 걸기 * [대량 발신](/docs/operate/outbound/campaigns): CSV·Excel로 여러 건을 한 번에 발신하기 * [API로 플로우 작성 및 검증](/docs/build/flow/api-authoring): `flow` 필드로 플로우 에이전트를 작성하고 검증하기 * [실시간 음성 런타임 API 작성](/docs/build/single-prompt/gpt-live): GPT-Live, Grok Voice, Gemini Live 런타임 고르기 # 지식 베이스 문서 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/knowledge-documents/지식-베이스-문서-목록-조회 /api-reference/v3/openapi.json get /knowledges/{knowledge_id}/documents knowledge base에 연결된 source document 목록을 조회합니다. document type이나 처리 상태는 반복 query parameter로 필터링할 수 있습니다. # 지식 베이스 문서 삭제 Source: https://docs.tryvox.co/api-reference/v3/knowledge-documents/지식-베이스-문서-삭제 /api-reference/v3/openapi.json delete /knowledges/{knowledge_id}/documents/{document_id} knowledge base에서 source document 1건을 삭제하고 vector data를 제거합니다. 상위 knowledge base는 유지됩니다. # 지식 베이스 문서 생성 Source: https://docs.tryvox.co/api-reference/v3/knowledge-documents/지식-베이스-문서-생성 /api-reference/v3/openapi.json post /knowledges/{knowledge_id}/documents knowledge base 안에 text, webpage, file document를 생성합니다. document는 즉시 반환되며 처리는 비동기로 진행됩니다. # 지식 베이스 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/knowledges/지식-베이스-목록-조회 /api-reference/v3/openapi.json get /knowledges 인증된 워크스페이스(`organization_id`)가 보유한 knowledge base 목록을 조회합니다. source document 조회와 관리는 각 knowledge base 하위 document endpoint를 사용합니다. # 지식 베이스 삭제 Source: https://docs.tryvox.co/api-reference/v3/knowledges/지식-베이스-삭제 /api-reference/v3/openapi.json delete /knowledges/{knowledge_id} knowledge base와 그 source document를 삭제합니다. # 지식 베이스 생성 Source: https://docs.tryvox.co/api-reference/v3/knowledges/지식-베이스-생성 /api-reference/v3/openapi.json post /knowledges 빈 knowledge base를 생성합니다. 생성 후 text, webpage, file document를 추가합니다. # 메모리 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/memories/메모리-목록-조회 /api-reference/v3/openapi.json get /memories 인증된 워크스페이스(`organization_id`)의 활성 메모리를 고객과 에이전트 쌍으로 묶어 조회합니다. `customer_id`와 `agent_id` 중 하나 이상을 전달해야 합니다. 둘 다 생략하면 400 `VALIDATION_ERROR`를 반환합니다. 각 그룹은 활성 fact를 `static`과 `dynamic` tier로 나눕니다. 각 tier는 `created_at` 내림차순입니다. 그룹은 페이지 사이에서 나뉘지 않으며 `total_count`는 그룹 수입니다. 에이전트가 없으면 404 `AGENT_NOT_FOUND`를 반환합니다. # 메모리 삭제 Source: https://docs.tryvox.co/api-reference/v3/memories/메모리-삭제 /api-reference/v3/openapi.json delete /memories/{memory_id} 인증된 워크스페이스(`organization_id`)의 메모리 fact 하나를 만료 처리합니다. 데이터는 유지되며 상태가 `expired`로 바뀝니다. 워크스페이스 API 키로 요청하면 `expire_reason`은 `user_manual`, 관리자가 요청하면 `admin_manual`입니다. 이미 만료되었거나 없거나 다른 워크스페이스에 속한 ID는 404 `MEMORY_NOT_FOUND`를 반환합니다. 같은 고객과 에이전트 쌍의 메모리가 갱신되는 동안에는 최대 5초 기다린 뒤 409 `MEMORY_LOCKED`를 반환합니다. # 메모리 생성 Source: https://docs.tryvox.co/api-reference/v3/memories/메모리-생성 /api-reference/v3/openapi.json post /memories 인증된 워크스페이스(`organization_id`)에서 고객과 에이전트 쌍에 메모리 fact 하나를 직접 추가합니다. 통화와 채팅이 끝난 뒤 실행되는 자동 추출은 tier를 스스로 정하지만, 이 직접 생성 요청에서는 요청자가 `tier`를 선택합니다. ID와 상태는 서버가 부여합니다. tier마다 보관 한도가 있으며, 한도를 넘으면 오래된 fact부터 만료합니다. 저장 전에 앞뒤 공백을 제거하고, 연속된 공백을 하나로 합치며, 문장 부호를 제거해 중복을 비교합니다. 같은 고객, 에이전트, tier에 정규화 결과가 같은 활성 fact가 있으면 새 fact를 만들지 않고 기존 fact를 201 응답으로 반환합니다. 에이전트가 없으면 404 `AGENT_NOT_FOUND`를 반환합니다. 고객이 없거나 다른 워크스페이스에 속하면 404 `CUSTOMER_NOT_FOUND`를 반환합니다. 응답은 생성된 fact와 `status`입니다. 과거 `observed_at` 때문에 tier가 한도를 넘어 방금 만든 fact가 먼저 만료되면 `expired`, 그렇지 않으면 `active`입니다. 같은 고객과 에이전트 쌍의 메모리가 갱신되는 동안에는 최대 5초 기다린 뒤 409 `MEMORY_LOCKED`를 반환합니다. # 메모리 일괄 만료 Source: https://docs.tryvox.co/api-reference/v3/memories/메모리-일괄-만료 /api-reference/v3/openapi.json post /memories/reset 인증된 워크스페이스(`organization_id`)의 활성 메모리를 조건에 따라 일괄 만료합니다. `customer_id`와 `agent_id` 중 하나 이상을 전달해야 하며, 둘 다 생략하면 400 `VALIDATION_ERROR`를 반환합니다. `agent_id`만 보내면 해당 에이전트의 모든 고객 메모리를 만료합니다. `customer_id`만 보내면 해당 고객의 모든 에이전트 메모리를 만료합니다. 대상이 없어도 204를 반환하는 멱등 동작이며, 이후에도 새 fact를 추가할 수 있습니다. 에이전트가 없으면 404 `AGENT_NOT_FOUND`를 반환합니다. # 메모리 조회 Source: https://docs.tryvox.co/api-reference/v3/memories/메모리-조회 /api-reference/v3/openapi.json get /memories/{memory_id} 인증된 워크스페이스(`organization_id`)의 활성 메모리 fact 하나를 출처와 함께 조회합니다. 만료되었거나 없거나 다른 워크스페이스에 속한 ID는 404 `MEMORY_NOT_FOUND`로 처리합니다. `agent_id`는 공개 UUID입니다. # LLM 모델 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/models/llm-모델-목록-조회 /api-reference/v3/openapi.json get /models/llms `agent.data.llm.model`에 사용할 수 있는 LLM 모델 목록을 조회합니다. 가능한 경우 temperature 범위 같은 capability 정보도 함께 반환합니다. # 음성 모델 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/models/음성-모델-목록-조회 /api-reference/v3/openapi.json get /models/voices `agent.data.voice`에 사용할 수 있는 음성 모델 목록을 조회합니다. 워크스페이스(`organization_id`) 전용 보이스도 포함합니다. 다음 페이지는 `next_cursor`를 `cursor`로 다시 전달해 조회합니다. `is_public: false`는 삭제 가능한 워크스페이스 전용 보이스를 나타냅니다. # 음성 모델 삭제 Source: https://docs.tryvox.co/api-reference/v3/models/음성-모델-삭제 /api-reference/v3/openapi.json delete /models/voices/{voice_id} 워크스페이스(`organization_id`) 전용으로 생성한 보이스 클론을 삭제합니다. 공개 카탈로그 보이스는 삭제할 수 없으며 `403`을 반환합니다. 다른 워크스페이스의 보이스와 존재하지 않는 보이스는 동일하게 `404`를 반환합니다. # 음성 모델 생성 Source: https://docs.tryvox.co/api-reference/v3/models/음성-모델-생성 /api-reference/v3/openapi.json post /models/voices 오디오 샘플로 워크스페이스(`organization_id`) 전용 보이스 클론을 생성합니다. `multipart/form-data`로 `clip` 오디오 파일과 `name`, `language` 필드를 보냅니다. 오디오 파일은 6MB 이하여야 합니다. 생성된 보이스는 `GET /v3/models/voices` 목록에 나타나며 `agent.data.voice`로 사용할 수 있습니다. 클론 한도에 도달하면 요청은 409 `VOICE_CLONE_LIMIT_REACHED`로 실패하며, `error.details.current_count`와 `error.details.limit`로 현재 사용량과 요금제 한도를 반환합니다. # 네이버톡톡 연동 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-목록-조회 /api-reference/v3/openapi.json get /navertalk-connections 워크스페이스(`organization_id`)의 네이버톡톡 연동 목록을 조회합니다. 해제된 연동도 포함하며, 토큰과 연동 확인 코드는 반환하지 않습니다. # 네이버톡톡 연동 생성 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-생성 /api-reference/v3/openapi.json post /navertalk-connections 중지 상태의 네이버톡톡 연동과 15분 동안 유효한 확인 코드를 생성합니다. API 서버 주소에 `webhook_path`를 붙인 URL을 네이버 파트너센터에 등록한 뒤, 고객용 톡톡 대화창에서 확인 코드를 보내야 합니다. 토큰을 저장하는 것만으로는 연동 확인이나 활성화가 끝나지 않습니다. # 네이버톡톡 연동 수정 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-수정 /api-reference/v3/openapi.json patch /navertalk-connections/{connection_id} 중지된 연동의 설정을 수정합니다. 토큰이나 파트너 ID를 바꾸면 기존 연동 확인이 무효가 됩니다. 설정을 바꾸면 이전 버전에서 대기하던 작업은 실행하지 않습니다. 에이전트 변경은 새로 만들어지는 채팅부터 적용됩니다. # 네이버톡톡 연동 조회 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-조회 /api-reference/v3/openapi.json get /navertalk-connections/{connection_id} 저장된 연동 설정과 연동 확인 결과를 조회합니다. 이 요청은 네이버와의 현재 연결 상태를 점검하지 않습니다. # 네이버톡톡 연동 중지 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-중지 /api-reference/v3/openapi.json post /navertalk-connections/{connection_id}/disable 새 AI 처리를 멈추고 대기 중인 발신을 막습니다. 이미 네이버로 보내기 시작한 요청은 취소할 수 없습니다. 중지된 연동에 다시 요청해도 상태는 바뀌지 않습니다. # 네이버톡톡 연동 해제 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-해제 /api-reference/v3/openapi.json delete /navertalk-connections/{connection_id} 연동을 중지하고 저장한 토큰을 삭제합니다. 대화 기록과 중복 발신 방지 기록은 보존 정책에 따라 유지됩니다. 해제한 연동은 다시 활성화할 수 없으며, 다시 연결하려면 새 연동을 생성해야 합니다. 네이버 파트너센터의 웹훅 URL은 따로 삭제해야 합니다. # 네이버톡톡 연동 활성화 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-연동-활성화 /api-reference/v3/openapi.json post /navertalk-connections/{connection_id}/enable 연동 확인을 마쳤고 활성 플랜과 유효한 채팅 에이전트가 있는 연동을 활성화합니다. 이전 버전에서 받은 입력은 다시 처리하지 않습니다. 이미 활성인 연동에 다시 요청해도 상태는 바뀌지 않습니다. # 네이버톡톡 확인 코드 재발급 Source: https://docs.tryvox.co/api-reference/v3/navertalk/네이버톡톡-확인-코드-재발급 /api-reference/v3/openapi.json post /navertalk-connections/{connection_id}/verification 중지된 연동에 15분 동안 유효한 새 확인 코드를 발급합니다. 이전 확인 코드와 연동 확인 결과는 모두 무효가 됩니다. 이 요청은 네이버로 메시지를 보내지 않습니다. # 상담사 통화 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/operator-calls/상담사-통화-목록-조회 /api-reference/v3/openapi.json get /operator-calls 인증된 워크스페이스(`organization_id`)의 상담사 통화를 조회합니다. 결과는 레코드 생성 시각인 `requested_at`순으로 정렬합니다. `start_at` 필터는 사람 상담 구간 시작 시각을 기준으로 적용합니다. # 상담사 통화 조회 Source: https://docs.tryvox.co/api-reference/v3/operator-calls/상담사-통화-조회 /api-reference/v3/openapi.json get /operator-calls/{operator_call_id} 상담사 통화 한 건을 조회합니다. 전체 사람 상담 대화록, 사용 가능한 경우 15분 동안 유효한 서명된 녹음 URL, 상담사 통화 비용을 포함합니다. # 보유 전화번호 SIP 설정 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-sip-설정 /api-reference/v3/openapi.json patch /organization-telephone-numbers/{organization_telephone_number_id}/sip custom 전화번호의 SIP trunk 설정을 수정합니다. # 보유 전화번호 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-목록-조회 /api-reference/v3/openapi.json get /organization-telephone-numbers 인증된 워크스페이스(`organization_id`)가 보유한 전화번호 목록을 조회합니다. 에이전트 매핑, SIP 설정, 해지 요청에는 각 항목의 `id`를 사용합니다. # 보유 전화번호 상세 조회 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-상세-조회 /api-reference/v3/openapi.json get /organization-telephone-numbers/{organization_telephone_number_id} 워크스페이스(`organization_id`)가 보유한 전화번호 1건을 API `id`로 조회합니다. # 보유 전화번호 수정 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-수정 /api-reference/v3/openapi.json patch /organization-telephone-numbers/{organization_telephone_number_id} 워크스페이스(`organization_id`)가 보유한 전화번호의 수정 가능한 메타데이터를 변경합니다. 에이전트 매핑과 SIP 설정은 별도 endpoint에서 관리합니다. # 보유 전화번호 에이전트 설정 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-에이전트-설정 /api-reference/v3/openapi.json patch /organization-telephone-numbers/{organization_telephone_number_id}/agent 전화번호의 인바운드/아웃바운드 에이전트 매핑을 설정하거나 해제합니다. # 보유 전화번호 통신서비스 이용증명원 발급 요청 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-통신서비스-이용증명원-발급-요청 /api-reference/v3/openapi.json post /organization-telephone-numbers/{organization_telephone_number_id}/certificate 워크스페이스(`organization_id`)가 보유한 전화번호의 통신서비스 이용증명원 발급 요청을 생성합니다. 사용자를 같은 탭에서 `verification_url`로 이동시켜 본인인증을 완료하도록 하세요. URL은 30분간 유효합니다. 발급이 끝나면 `GET /v3/files/{file_key}/content`로 PDF를 내려받습니다. 발급 전에는 해당 엔드포인트가 404를 반환합니다. # 보유 전화번호 해지 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-해지 /api-reference/v3/openapi.json delete /organization-telephone-numbers/{organization_telephone_number_id} 워크스페이스(`organization_id`)가 보유한 전화번호를 해지 요청하거나 만료 처리합니다. # 보유 전화번호 해지 취소 Source: https://docs.tryvox.co/api-reference/v3/organization-telephone-numbers/보유-전화번호-해지-취소 /api-reference/v3/openapi.json post /organization-telephone-numbers/{organization_telephone_number_id}/revoke-cancel 워크스페이스(`organization_id`)가 보유한 vox.ai 번호의 해지 예약을 취소합니다. # API 키 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/organizations/api-키-목록-조회 /api-reference/v3/openapi.json get /organizations/{organization_id}/api-keys 하위 워크스페이스(`organization_id`)의 마스킹된 API 키 목록을 조회합니다. 각 항목에는 `key_name`, `secret_key_suffix`, `created_at`, `last_used_at`이 포함됩니다. 하위 워크스페이스의 키로 본인 워크스페이스를 조회하고, 상위 워크스페이스의 키로 직속 하위 워크스페이스를 조회할 수 있습니다. 상위 워크스페이스의 키로 자기 워크스페이스의 키를 관리할 수 없으며 403을 반환합니다. 평문 키와 해시된 키는 모두 노출하지 않습니다. # API 키 발급 Source: https://docs.tryvox.co/api-reference/v3/organizations/api-키-발급 /api-reference/v3/openapi.json post /organizations/{organization_id}/api-keys 하위 워크스페이스(`organization_id`)의 API 키를 발급합니다. 하위 워크스페이스의 키로 본인 워크스페이스에, 상위 메인 워크스페이스의 키로 바로 아래 하위 워크스페이스에 접근할 수 있습니다. 메인 워크스페이스의 자체 키는 이 API로 관리할 수 없으며 403을 반환합니다. 평문 `api_key`는 이 응답에서 한 번만 반환하므로 즉시 저장해야 합니다. `key_name`은 필수이며, 키 폐기 시 `key_name`과 `secret_key_suffix` 조합으로 식별합니다. 내부 키 ID는 노출하지 않습니다. 하위 워크스페이스마다 API 키를 최대 20개 보유할 수 있습니다. JWT 호출자는 대상 워크스페이스의 소유자 또는 관리자여야 합니다. # API 키 폐기 Source: https://docs.tryvox.co/api-reference/v3/organizations/api-키-폐기 /api-reference/v3/openapi.json delete /organizations/{organization_id}/api-keys 하위 워크스페이스(`organization_id`)의 API 키를 폐기합니다. JWT 호출자는 대상 워크스페이스의 소유자 또는 관리자여야 합니다. 필수 쿼리인 `key_name`과 `secret_key_suffix` 조합으로 키를 식별하며, 하위 워크스페이스 자체 키 또는 상위 메인 워크스페이스의 키로 접근할 수 있습니다. 메인 워크스페이스의 자체 키는 이 API로 관리할 수 없으며 403을 반환합니다. 내부 키 ID는 노출하지 않습니다. 다른 워크스페이스 소유의 키를 포함해 일치하는 키가 없으면 404 `API_KEY_NOT_FOUND`, 둘 이상이면 409 `API_KEY_AMBIGUOUS`를 반환하며 삭제하지 않습니다. # 워크스페이스 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/organizations/워크스페이스-목록-조회 /api-reference/v3/openapi.json get /organizations 인증된 상위 워크스페이스(`organization_id`)와 그 직속 하위 워크스페이스를 한 목록으로 조회합니다. `is_main`으로 상위·하위 워크스페이스를 구분하며, 상위 워크스페이스 자신도 포함됩니다. 상위 워크스페이스의 API 키로만 호출할 수 있고, 하위 워크스페이스 키로 요청하면 권한이 없습니다. 구독 정보는 포함되지 않으며 단건 조회에서 확인합니다. # 워크스페이스 수정 Source: https://docs.tryvox.co/api-reference/v3/organizations/워크스페이스-수정 /api-reference/v3/openapi.json patch /organizations/{organization_id} 본인 워크스페이스 또는 바로 아래 하위 워크스페이스(`organization_id`)의 지정한 필드를 수정합니다. 생략한 필드는 유지하며, 계층과 결제 설정은 이 API로 변경할 수 없습니다. Supabase JWT 호출자가 이름과 청구서 수신자를 변경하려면 대상 워크스페이스의 소유자 또는 관리자여야 합니다. 웹훅 필드는 모든 멤버가 변경할 수 있습니다. 그 외 ID는 404, 하위 워크스페이스가 상위 워크스페이스를 수정하면 403을 반환합니다. # 워크스페이스 인증 상태 조회 Source: https://docs.tryvox.co/api-reference/v3/organizations/워크스페이스-인증-상태-조회 /api-reference/v3/openapi.json get /organizations/{organization_id}/verification 워크스페이스(`organization_id`)의 인증 상태를 조회합니다. 본인 워크스페이스와 직속 하위 워크스페이스를 조회할 수 있습니다. `latest`는 가장 최근 인증 기록이며(신청 이력이 없으면 `null`), 상태는 `requested`(자동 확인 중), `pending`(수동 심사 중), `approved`(승인), `rejected`(반려, 사유는 `rejection_reason`), `revoked`(철회)입니다. `currently_verified`와 `current_grade`는 현재 유효한 승인을 나타내며, 재인증이 진행 중이어도 이전 승인은 유지됩니다. # 워크스페이스 인증 신청 Source: https://docs.tryvox.co/api-reference/v3/organizations/워크스페이스-인증-신청 /api-reference/v3/openapi.json post /organizations/{organization_id}/verification 워크스페이스(`organization_id`) 인증을 `multipart/form-data`로 제출합니다. 사업자 유형(`sole_proprietor`/`corporation`)은 `verification_case`와 `business_registration` 서류가 필수입니다. 직원 신청은 `employment_certificate`도 필요합니다. `personal`은 서류가 없으며 `verification_case`를 지정하면 안 됩니다. 신분증은 수집하지 않으며, 기존 `identity_document` 파트를 보내면 400 `IDENTITY_DOCUMENT_NOT_ACCEPTED`를 반환합니다. 신청자는 본인인증을 완료한 멤버여야 하며, 생략하면 워크스페이스 소유자를 사용합니다. JWT 호출자는 제출·재제출 시 대상 워크스페이스의 소유자 또는 관리자여야 합니다. 워크스페이스마다 인증 하나만 진행할 수 있습니다. 202와 생성된 기록의 `id`(상태 `requested`)를 반환합니다. 서류 확인과 승인은 비동기로 진행되므로 GET 엔드포인트를 주기적으로 조회해 결과를 확인합니다. # 워크스페이스 조회 Source: https://docs.tryvox.co/api-reference/v3/organizations/워크스페이스-조회 /api-reference/v3/openapi.json get /organizations/{organization_id} 워크스페이스(`organization_id`) 1건을 조회합니다. 본인 워크스페이스와 직속 하위 워크스페이스를 조회할 수 있습니다. 상위 워크스페이스는 구독 정보가 `subscription`에 포함되고, 하위 워크스페이스는 `subscription`이 `null`입니다. 접근 권한이 없는 워크스페이스는 찾을 수 없는 것으로 처리되며, 하위 워크스페이스가 상위 워크스페이스를 조회하면 권한이 없습니다. # 하위 워크스페이스 삭제 Source: https://docs.tryvox.co/api-reference/v3/organizations/하위-워크스페이스-삭제 /api-reference/v3/openapi.json delete /organizations/{organization_id} 하위 워크스페이스(`organization_id`)를 삭제합니다. JWT 호출자는 상위 워크스페이스의 소유자 또는 관리자여야 하며, 대상은 바로 아래 하위 워크스페이스여야 합니다. 전화번호와 부가서비스는 즉시 해지하고 대기 중인 대량 발신은 취소합니다. 남은 청구서가 있어도 삭제할 수 있습니다. 열린 청구서는 지연 도착한 통화 상세 기록(CDR)·SMS 요금 반영을 위해 유지하고 정기 월 마감 작업에서 마감합니다. 마감되거나 발행된 청구서는 다음 청구 주기에도 유지됩니다. 삭제에 성공하면 해당 하위 워크스페이스의 모든 API 키를 폐기합니다. # 하위 워크스페이스 생성 Source: https://docs.tryvox.co/api-reference/v3/organizations/하위-워크스페이스-생성 /api-reference/v3/openapi.json post /organizations 인증된 워크스페이스 아래에 하위 워크스페이스를 생성합니다. JWT 호출자는 상위 워크스페이스의 소유자 또는 관리자여야 합니다. 선택 설정인 `webhook_url`, `webhook_event_subscriptions`, `billing_invoice_recipient_emails`는 전달하면 적용하고 생략하면 기본값을 사용합니다. 청구서 수신 이메일을 지정하지 않으면 상위 워크스페이스의 값을 상속합니다. # Public launch audit Source: https://docs.tryvox.co/api-reference/v3/public-launch-audit # v3 Public Launch Audit Checklist > PR #12 작업용 내부 체크리스트입니다. v3 public launch 문서를 > `domains/voxai/api-server`의 현재 구현과 맞춰 보고, endpoint별로 검증 > 상태를 체크하면서 수정합니다. ## 목표 v3 API reference와 관련 가이드가 current `api-server` public contract와 일치하도록 검증하고, 잘못된 예시, 설명, 스키마, 누락된 제약을 최소 수정으로 고칩니다. ## 작업 원칙 * 먼저 이 파일에 증거와 상태를 기록합니다. * 문서 수정은 체크리스트에 근거를 남긴 뒤 수행합니다. * source of truth는 current `api-server` 코드, generated public OpenAPI, v3 schema, service validation, tests입니다. * 코드와 문서가 충돌하면 문서를 고칩니다. * 코드 contract 자체가 불명확하면 `UNVERIFIED` 또는 `ISSUE`로 남깁니다. * endpoint별 상태는 `TODO`, `PASS`, `FIXED`, `ISSUE`, `UNVERIFIED` 중 하나로 표시합니다. ## Source Of Truth | 항목 | 위치 | | - | - | | Docs PR branch | `domains/voxai/docs`, branch `codex-v3-api-reference` | | Docs OpenAPI | `api-reference/v3/openapi.json` | | Docs navigation | `docs.json` > `API 참조` > `v3` | | API server | `domains/voxai/api-server` | | v3 app mount | `app/main.py` | | v3 router | `app/api/v3/router.py` | | v3 endpoint handlers | `app/api/v3/endpoints/*.py` | | v3 schemas | `app/api/v3/schemas/**` | | public OpenAPI generator | `scripts/generate_v3_public_openapi.py` | | contract audit script | `scripts/v3_audit.py` | | v3 tests | `tests/v3/**` | ## Baseline Evidence * [x] Checked out correct docs submodule branch: `domains/voxai/docs` > `codex-v3-api-reference`. * [x] Read nearest `AGENTS.md` in `domains/voxai/docs`. * [x] Read `api-server` `AGENTS.md` and `ARCHITECTURE.md`. * [x] Generated current api-server public OpenAPI: `uv run python scripts/generate_v3_public_openapi.py --output /tmp/current-v3-public-openapi.json --servers-from /Users/ryanhan/Documents/development/voxai/vox-mono/domains/voxai/docs/api-reference/v3/openapi.json` * [x] Compared docs OpenAPI operations against generated api-server operations. * [x] Ran `scripts/v3_audit.py` against current docs OpenAPI: 7 blockers, 6 warnings, 1 info. * [x] Replace stale docs OpenAPI after reviewing the generated diff. * [x] Update `docs.json` navigation after reviewing missing public operations. * [x] Re-ran API-side audit with the 4 confirmed-private flow helper endpoints passed as intentional excludes. Result: 0 blockers, 52 warnings, 1 info for accepted exclusions. Without those explicit excludes, current api-server still reports exactly those 4 endpoints as missing from public OpenAPI. * [x] Run docs validation after edits. * [x] Verified docs OpenAPI contract is equal to expected api-server OpenAPI after removing the 4 confirmed-private flow helper endpoints, pruning unreachable schemas, and ignoring docs-localized `description`/`summary` text. * [x] Verified docs OpenAPI operation list equals v3 `docs.json` navigation operation list. * [x] Verified stale v2 endpoint examples and versionless API reference links are gone from v3 launch guide pages; historical changelog entries intentionally keep v2 links where the release predates v3. * [x] Patched `scripts/sync-openapi.sh` so future live OpenAPI syncs keep the 4 confirmed-private flow helper endpoints and their private-only schemas out of the docs snapshot. * [x] Ran `mint validate` with Node 20.18 in PATH: build validation passed. * [x] Ran `mint broken-links` with Node 20.18 in PATH: no broken links found. ### Baseline Findings | Status | Finding | Evidence | Next Action | | - | - | - | - | | PASS | Docs OpenAPI has 58 operations; current api-server generated public OpenAPI has 62 before docs-side public-scope filtering. | Re-generated api-server OpenAPI from current source: `paths=45 ops=62 schemas=176 pruned_schemas=16`. After removing the 4 confirmed-private helpers and pruning unreachable schemas, the filtered source contract has 58 operations and 161 schemas. | Keep these endpoints out of public docs unless product scope changes. | | FIXED | Docs OpenAPI/navigation included private flow operations after an over-broad generated-spec sync. | Removed `POST /agents/validate-flow-data`, `POST /agents/autofix-flow-data`, `POST /agents/{agent_id}/operations`, and `POST /flow-data/autofix` from docs OpenAPI and v3 navigation. | Consider aligning api-server generator/audit allowlist so these are treated like hidden routes. | | FIXED | Docs sync script could reintroduce private flow helpers on the next live OpenAPI sync. | `scripts/sync-openapi.sh` now deletes all 4 confirmed-private paths and their private-only component schemas before writing `api-reference/v3/openapi.json`. | Keep docs-side filter until api-server generator/audit scope is aligned. | | FIXED | Generated OpenAPI descriptions were too English-heavy for the Korean public docs surface. | Localized v3 operation descriptions, request-body descriptions, shared response descriptions, and high-visibility schema descriptions in `api-reference/v3/openapi.json`. | Keep code identifiers and enum values in English, but avoid English prose in user-facing docs text. | | ISSUE | API-side generator/audit still treats the 4 flow helper endpoints as public candidates unless they are passed as intentional excludes. | `scripts/v3_audit.py` exits 0 with the 4 explicit excludes, but exits 1 with exactly those 4 endpoint-parity blockers without them. The api-server companion PR was closed and removed from scope. | Keep docs-side sync filter; revisit api-server generator/audit scope separately if product wants source tooling to encode this public/private split. | | PASS | Endpoint-by-endpoint docs surface review completed for 58 public operations. | Docs OpenAPI is source-generated, private endpoints are excluded, examples validate, navigation matches OpenAPI, and `scripts/v3_audit.py` reports 0 blockers when the 4 confirmed-private helpers are passed as intentional excludes. | Re-run the full pass before public launch if api-server v3 routes change. | Confirmed-private operations kept out of public scope: * `POST /agents/autofix-flow-data` * `POST /agents/validate-flow-data` * `POST /agents/{agent_id}/operations` * `POST /flow-data/autofix` Audit warning triage: * `UNREVIEWED_CAMEL_CASE_PROPERTY` warnings are restricted to `agent.data` / `flow_data` payload internals and are documented as explicit compatibility exceptions in `api-reference/v3/introduction.mdx`. * `ORG_ID_NOT_USED_IN_HANDLER` warnings are limited to authenticated catalog reads (`models`, `schemas`, available telephone lines) and an excluded traffic split endpoint. Org-owned resources still require org context. * Knowledge endpoint import-boundary warnings are source architecture debt, but the public request/response schema is still generated from v3 response models and does not expose provider or persistence types. ## Cross-Cutting Review Checklist | Status | Area | What To Check | Evidence | | - | - | - | - | | PASS | Public route inventory | Every public api-server operation appears in docs OpenAPI and v3 navigation. | Docs OpenAPI/nav are internally aligned at 58 operations after excluding 4 confirmed-private flow helper endpoints. | | PASS | Hidden route pruning | Routes intentionally excluded from public launch stay hidden. | `scripts/sync-openapi.sh` deletes the 4 confirmed-private helper paths and private-only schemas; audit reports 1 accepted-exclusion info when those helpers are passed as intentional excludes. | | PASS | Authentication | All operations document bearer organization API key auth. | `BearerAuth` is present and no operation has empty `security`. | | PASS | Error envelope | Error responses use `{ "error": { "code", "message", "details" } }`. | `scripts/v3_audit.py` error envelope check passed for docs OpenAPI after excluding private endpoints. | | PASS | Error codes | Endpoint-specific error codes are present where available. | `scripts/v3_audit.py` error code metadata check passed for docs OpenAPI after excluding private endpoints. | | PASS | Pagination | List endpoints use `cursor`, `limit`, `items`, `next_cursor`, `total_count`. | `scripts/v3_audit.py` pagination contract check passed for docs OpenAPI after excluding private endpoints. | | PASS | Timestamp format | `_at` fields use unix ms; seconds compatibility is documented only where code supports it. | `scripts/v3_audit.py` timestamp contract check passed for docs OpenAPI after excluding private endpoints. | | PASS | Request examples | Examples validate against the generated request schema and service-level validation. | Public OpenAPI has 12 JSON request examples; all 12 validate against their request schemas with `jsonschema` in the api-server uv environment. | | PASS | Response schemas | Response schemas match endpoint `response_model`. | Docs OpenAPI contract matches expected api-server generated OpenAPI after excluding 4 confirmed-private endpoints, pruning schemas, and ignoring localized `description`/`summary` text. | | PASS | PATCH semantics | Partial updates, null clearing, empty payload behavior, and nested object handling are accurate. | `scripts/v3_audit.py` patch contract check passed for docs OpenAPI after excluding private endpoints. | | FIXED | Agent data casing | General API uses snake\_case; `agent.data` and `flow_data` camelCase exceptions are explicit. | Updated `api-reference/v3/introduction.mdx` to mention both `agent.data` and `flow_data` camelCase exceptions. | | PASS | Flow data | Node/edge examples use canonical runtime fields accepted by validator. | `POST /agents` flow example validates against generated request schema; private flow helper endpoints are excluded from public docs. | | PASS | Knowledge IDs | Public docs consistently use numeric `knowledge_id`, not UUID. | OpenAPI path params use integer `knowledge_id`; `AgentKnowledge.knowledgeIds` and `NodeKnowledgeConfig.knowledgeIds` describe numeric public IDs from `GET /v3/knowledges`; strict request validation tests exist in `tests/v3/unit/test_knowledge_strict_validation.py`. | | PASS | Org scope | Cross-resource references are org-scoped, or marked `UNVERIFIED`. | `scripts/v3_audit.py` reference scope check passed. Resource handlers use `auth.require_organization_id()`; agent runtime references validate LLM/voice/tool/knowledge refs with org context; model/schema catalog endpoints are authenticated public catalog reads. | | FIXED | Guides | Guide pages do not point users to stale v2 endpoints for v3 launch flows. | Updated `docs/build/variables/dynamic-variables.mdx` from v2 calls/campaigns examples to v3 request shape. | | FIXED | Links | API reference links point to `/api-reference/v3/introduction` or exact v3 endpoint pages. | Updated guide links to `/api-reference/v3/introduction`; `exports.mdx` now points to `GET /calls` and `GET /calls/{call_id}` instead of a nonexistent v3 export endpoint. | | PASS | Build validation | Mintlify/docs validation passes or failure is recorded. | `PATH="/Users/ryanhan/.nvm/versions/node/v20.18.0/bin:$PATH" mint validate` passed; `mint broken-links` passed. | ## Detailed Endpoint Verification Matrix Every public operation was checked one by one against the current docs OpenAPI, the v3 navigation, and a freshly regenerated api-server OpenAPI after removing the four confirmed-private helper endpoints. `Examples` is the count of request examples currently present in OpenAPI. `0` means no explicit request example is published for that request body; it does not indicate a failing example. | Status | Operation | Nav | Auth | Request | Examples | Success Response | Errors | Source | | - | - | - | - | - | -: | - | - | - | | PASS | `GET /calls/{call_id}` | yes | BearerAuth | none | n/a | 200:application/json:CallResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /calls` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_CallListItemResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /calls` | yes | BearerAuth | application/json:CreateCallRequest | 2 | 201:application/json:CallResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /campaigns/{campaign_id}` | yes | BearerAuth | none | n/a | 200:application/json:CampaignResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /campaigns/{campaign_id}` | yes | BearerAuth | application/json:UpdateCampaignV3Request | 0 | 200:application/json:CampaignResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /campaigns` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_CampaignResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /campaigns` | yes | BearerAuth | application/json:CreateCampaignV3Request | 2 | 201:application/json:CampaignResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /campaigns/{campaign_id}/cancel` | yes | BearerAuth | none | n/a | 200:application/json:CancelCampaignV3Response | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /campaigns/{campaign_id}/pause` | yes | BearerAuth | none | n/a | 200:application/json:PauseCampaignV3Response | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /campaigns/{campaign_id}/resume` | yes | BearerAuth | none | n/a | 200:application/json:ResumeCampaignV3Response | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /telephone-numbers/available` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_AvailableTelephoneLineResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /telephone-numbers/purchase` | yes | BearerAuth | application/json:PurchaseNumberRequest | 0 | 201:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /telephone-numbers/register` | yes | BearerAuth | application/json:RegisterNumberRequest | 2 | 201:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /organization-telephone-numbers` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_TelephoneNumberResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /organization-telephone-numbers/{organization_telephone_number_id}` | yes | BearerAuth | none | n/a | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /organization-telephone-numbers/{organization_telephone_number_id}` | yes | BearerAuth | application/json:UpdateTelephoneNumberRequest | 0 | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `DELETE /organization-telephone-numbers/{organization_telephone_number_id}` | yes | BearerAuth | none | n/a | 200:application/json:DeleteTelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /organization-telephone-numbers/{organization_telephone_number_id}/agent` | yes | BearerAuth | application/json:UpdateAgentMappingRequest | 0 | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /organization-telephone-numbers/{organization_telephone_number_id}/sip` | yes | BearerAuth | application/json:UpdateSipConfigRequest | 0 | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /organization-telephone-numbers/{organization_telephone_number_id}/revoke-cancel` | yes | BearerAuth | none | n/a | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /alert-rules` | yes | BearerAuth | application/json:CreateAlertRuleRequest | 0 | 201:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /alert-rules` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_AlertRuleResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /alert-rules/{alert_rule_id}` | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /alert-rules/{alert_rule_id}` | yes | BearerAuth | application/json:UpdateAlertRuleRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `DELETE /alert-rules/{alert_rule_id}` | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /alert-rules/{alert_rule_id}/condition` | yes | BearerAuth | application/json:UpdateConditionRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /alert-rules/{alert_rule_id}/channels` | yes | BearerAuth | application/json:UpdateChannelsRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /alert-rules/{alert_rule_id}/schedule` | yes | BearerAuth | application/json:UpdateScheduleRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /alert-rules/{alert_rule_id}/enable` | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /alert-rules/{alert_rule_id}/disable` | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /alert-rules/{alert_rule_id}/pause` | yes | BearerAuth | application/json:PauseAlertRuleRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /alert-rules/{alert_rule_id}/resume` | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /alert-rules/{alert_rule_id}/incidents` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_AlertIncidentResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /alert-rules/{alert_rule_id}/test-notification` | yes | BearerAuth | none | n/a | 200:application/json:TestNotificationResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /incidents` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_AlertIncidentResponse\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /tools` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_ToolSummary\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /tools` | yes | BearerAuth | application/json:CreateToolRequest | 2 | 201:application/json:ToolDetail | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /tools/{tool_id}` | yes | BearerAuth | none | n/a | 200:application/json:ToolDetail | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /tools/{tool_id}` | yes | BearerAuth | application/json:UpdateToolRequest | 0 | 200:application/json:ToolDetail | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `DELETE /tools/{tool_id}` | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /schemas` | yes | BearerAuth | none | n/a | 200:application/json:ListSchemasResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /schemas/{namespace}/{schema_type}` | yes | BearerAuth | none | n/a | 200:application/json:SchemaDefinition | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /knowledges` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_KnowledgeSummary\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /knowledges` | yes | BearerAuth | application/json:CreateKnowledgeRequest | 0 | 201:application/json:KnowledgeSummary | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `DELETE /knowledges/{knowledge_id}` | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /knowledges/{knowledge_id}/documents` | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse\_KnowledgeDocumentSummary\_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /knowledges/{knowledge_id}/documents` | yes | BearerAuth | application/json:oneOf(CreateTextDocumentRequest\|CreateWebpageDocumentRequest); multipart/form-data:object | 0 | 201:application/json:KnowledgeDocumentSummary | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `DELETE /knowledges/{knowledge_id}/documents/{document_id}` | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /agents` | yes | BearerAuth | application/json:CreateAgentRequest | 2 | 201:application/json:AgentMutationResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /agents` | yes | BearerAuth | none | n/a | 200:application/json:ListAgentsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /agents/{agent_id}` | yes | BearerAuth | none | n/a | 200:application/json:AgentResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `PATCH /agents/{agent_id}` | yes | BearerAuth | application/json:UpdateAgentRequest | 2 | 200:application/json:AgentMutationResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `DELETE /agents/{agent_id}` | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /agents/{agent_id}/versions` | yes | BearerAuth | application/json:CreateAgentVersionRequest | 0 | 201:application/json:CreateAgentVersionResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /agents/{agent_id}/versions` | yes | BearerAuth | none | n/a | 200:application/json:ListAgentVersionsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `POST /agents/{agent_id}/versions/{version}/publish` | yes | BearerAuth | none | n/a | 200:application/json:PublishAgentVersionResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /models/llms` | yes | BearerAuth | none | n/a | 200:application/json:ListLLMModelsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | | PASS | `GET /models/voices` | yes | BearerAuth | none | n/a | 200:application/json:ListVoiceModelsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match | ## Endpoint Checklist `PASS` in this section means the public documentation surface was checked for path, method, navigation, bearer auth, request schema, response schema, documented errors, examples where present, and known guide references. It is not a blanket backend implementation sign-off; source-side generator/audit debt is tracked in the findings above and intentionally left outside this docs PR. ### Agents | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `POST /agents` | `api-reference/v3/openapi.json`, `docs.json` | `app/api/v3/endpoints/agent.py`, `app/api/v3/schemas/agent/**`, `tests/v3/integration/test_agent_endpoints.py` | create schema, single-prompt defaults, flow `flow_data` requirement, examples, 201 schema, strict refs | | PASS | `GET /agents` | same | same | pagination, filters, summary shape | | PASS | `GET /agents/{agent_id}` | same | same | version selector, response shape, 404 | | PASS | `PATCH /agents/{agent_id}` | same | same | partial update, empty nested dicts, null clearing, `flow_data` replacement, strict refs | | PASS | `DELETE /agents/{agent_id}` | same | same | 204, soft-delete semantics | | PASS | `POST /agents/validate-flow-data` | excluded from public docs | `app/api/v3/endpoints/flow_validation.py`, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. | | PASS | `POST /agents/autofix-flow-data` | excluded from public docs | `app/api/v3/endpoints/agent.py`, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. | | PASS | `POST /agents/{agent_id}/operations` | excluded from public docs | `app/api/v3/endpoints/agent.py`, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. | ### Agent Versions | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /agents/{agent_id}/versions` | OpenAPI, nav | `app/api/v3/endpoints/agent_version.py` | list shape, version names | | PASS | `POST /agents/{agent_id}/versions` | OpenAPI, nav | same | 201, snapshot semantics | | PASS | `POST /agents/{agent_id}/versions/{version}/publish` | OpenAPI, nav | same | version pattern, production publish behavior | ### Calls | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /calls` | OpenAPI, nav | `app/api/v3/endpoints/calls.py`, `tests/v3/calls/**` | filters, pagination, status mapping, timestamps | | PASS | `POST /calls` | OpenAPI, nav | same | request field names, `agent` mapping, traffic split behavior, dynamic variables example | | PASS | `GET /calls/{call_id}` | OpenAPI, nav | same | detail shape, transcript, `call_analysis`, not-found | ### Campaigns | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /campaigns` | OpenAPI, nav | `app/api/v3/endpoints/campaigns.py`, `tests/v3/campaigns/**` | filters, pagination, statuses | | PASS | `POST /campaigns` | OpenAPI, nav | same | tasks shape, `agent` mapping, `from_number`, dynamic variables, call windows | | PASS | `GET /campaigns/{campaign_id}` | OpenAPI, nav | same | detail shape | | PASS | `PATCH /campaigns/{campaign_id}` | OpenAPI, nav | same | editable fields and status guards | | PASS | `POST /campaigns/{campaign_id}/cancel` | OpenAPI, nav | same | action response, conflict cases | | PASS | `POST /campaigns/{campaign_id}/pause` | OpenAPI, nav | same | pause body, timestamp normalization | | PASS | `POST /campaigns/{campaign_id}/resume` | OpenAPI, nav | same | resume semantics | ### Telephone Numbers | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /organization-telephone-numbers` | OpenAPI, nav | `app/api/v3/endpoints/telephone_numbers.py`, telephone tests | filters, org-owned ID | | PASS | `GET /organization-telephone-numbers/{organization_telephone_number_id}` | OpenAPI, nav | same | ID type, response | | PASS | `PATCH /organization-telephone-numbers/{organization_telephone_number_id}` | OpenAPI, nav | same | mutable metadata | | PASS | `PATCH /organization-telephone-numbers/{organization_telephone_number_id}/agent` | OpenAPI, nav | same | inbound/outbound agent mapping, clear semantics | | PASS | `PATCH /organization-telephone-numbers/{organization_telephone_number_id}/sip` | OpenAPI, nav | same | SIP settings, custom number limits | | PASS | `DELETE /organization-telephone-numbers/{organization_telephone_number_id}` | OpenAPI, nav | same | cancel/delete semantics, response | | PASS | `POST /organization-telephone-numbers/{organization_telephone_number_id}/revoke-cancel` | OpenAPI, nav | same | revoke constraints | | PASS | `GET /telephone-numbers/available` | OpenAPI, nav | same | filters, purchasable line ID | | PASS | `POST /telephone-numbers/purchase` | OpenAPI, nav | same | `telephone_line_id`, not phone string | | PASS | `POST /telephone-numbers/register` | OpenAPI, nav | same | SIP registration example | ### Tools | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /tools` | OpenAPI, nav | `app/api/v3/endpoints/tools.py` | list summary vs detail | | PASS | `POST /tools` | OpenAPI, nav | same | API tool schema, auth config, examples | | PASS | `GET /tools/{tool_id}` | OpenAPI, nav | same | detail shape | | PASS | `PATCH /tools/{tool_id}` | OpenAPI, nav | same | partial update, auth shape parity | | PASS | `DELETE /tools/{tool_id}` | OpenAPI, nav | same | 204 delete | ### Schemas And Flow Data | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /schemas` | OpenAPI, nav | `app/api/v3/endpoints/schemas.py`, schema registry tests | namespace/category, `include_schema` | | PASS | `GET /schemas/{namespace}/{schema_type}` | OpenAPI, nav | same | schema body, version query, public names | | PASS | `POST /flow-data/autofix` | excluded from public docs | `app/api/v3/endpoints/flow_data.py`, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. | ### Knowledges | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /knowledges` | OpenAPI, nav | `app/api/v3/endpoints/knowledges.py`, knowledge tests | numeric ID, pagination, org scope | | PASS | `POST /knowledges` | OpenAPI, nav | same | request schema and response | | PASS | `DELETE /knowledges/{knowledge_id}` | OpenAPI, nav | same | 204, org-scope not-found | | PASS | `GET /knowledges/{knowledge_id}/documents` | OpenAPI, nav | same | list filters, statuses | | PASS | `POST /knowledges/{knowledge_id}/documents` | OpenAPI, nav | same | JSON vs multipart body, source types, ingestion trigger | | PASS | `DELETE /knowledges/{knowledge_id}/documents/{document_id}` | OpenAPI, nav | same | UUID document ID, 204, org scope | ### Models | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /models/llms` | OpenAPI, nav | `app/api/v3/endpoints/model.py`, model tests | pagination, capabilities | | PASS | `GET /models/voices` | OpenAPI, nav | same | provider/language filters, capabilities | ### Alerts And Incidents | Status | Operation | Docs Evidence | API Evidence | Checks | | - | - | - | - | - | | PASS | `GET /alert-rules` | OpenAPI, nav | `app/api/v3/endpoints/alert.py`, alert tests | filters, pagination | | PASS | `POST /alert-rules` | OpenAPI, nav | same | condition, channels, schedule | | PASS | `GET /alert-rules/{alert_rule_id}` | OpenAPI, nav | same | detail response | | PASS | `PATCH /alert-rules/{alert_rule_id}` | OpenAPI, nav | same | metadata patch | | PASS | `DELETE /alert-rules/{alert_rule_id}` | OpenAPI, nav | same | 204 delete | | PASS | `PATCH /alert-rules/{alert_rule_id}/channels` | OpenAPI, nav | same | replacement semantics | | PASS | `PATCH /alert-rules/{alert_rule_id}/condition` | OpenAPI, nav | same | metric/operators | | PASS | `PATCH /alert-rules/{alert_rule_id}/schedule` | OpenAPI, nav | same | `HH:MM`, timezone | | PASS | `POST /alert-rules/{alert_rule_id}/disable` | OpenAPI, nav | same | action response | | PASS | `POST /alert-rules/{alert_rule_id}/enable` | OpenAPI, nav | same | action response | | PASS | `POST /alert-rules/{alert_rule_id}/pause` | OpenAPI, nav | same | `until`, paused state | | PASS | `POST /alert-rules/{alert_rule_id}/resume` | OpenAPI, nav | same | action response | | PASS | `POST /alert-rules/{alert_rule_id}/test-notification` | OpenAPI, nav | same | side effect and response | | PASS | `GET /alert-rules/{alert_rule_id}/incidents` | OpenAPI, nav | same | pagination and status filters | | PASS | `GET /incidents` | OpenAPI, nav | same | org-wide list filters | ## Full Reverification Pass 2026-05-08 Objective restated as concrete deliverables: 1. Rebuild the checklist against the current docs PR branch and current `domains/voxai/api-server` source. 2. Check every public endpoint for method/path/nav/auth/request/response/errors. 3. Check examples, descriptions, schema descriptions, and public/private scope. 4. Compare docs OpenAPI with freshly generated api-server OpenAPI. 5. Run real validation gates and fix any issues found. Prompt-to-artifact checklist: | Requirement | Evidence | Status | | - | - | - | | Current branch state checked | `domains/voxai/docs` on `codex-v3-api-reference`; `domains/voxai/api-server` current checkout on `develop`. | PASS | | Every public endpoint checked | Detailed Endpoint Verification Matrix has 58 public operation rows; current OpenAPI operation count is 58. | PASS | | Public/private scope checked | `POST /agents/validate-flow-data`, `POST /agents/autofix-flow-data`, `POST /agents/{agent_id}/operations`, and `POST /flow-data/autofix` are absent from docs OpenAPI and nav. | PASS | | api-server generator compared | `ENV=development-ryan uv run python scripts/generate_v3_public_openapi.py ...` returned `paths=45 ops=62 schemas=176 pruned_schemas=16`; docs-side filtering of the 4 confirmed-private helpers yields 58 public operations and 161 schemas. | PASS | | Contract diff checked | Filtered generated api-server OpenAPI and docs OpenAPI match after pruning unreachable schemas and removing docs-localized `description`/`summary`. | PASS | | Navigation checked | v3 `docs.json` nav operation list has 58 entries and matches OpenAPI exactly. | PASS | | API-side audit checked | `ENV=development-ryan uv run python scripts/v3_audit.py --openapi-file ...` exits 0 with the 4 confirmed-private helpers passed as intentional excludes: 0 blockers, 52 warnings, 1 info. Without those ad-hoc excludes it exits 1 with exactly 4 known endpoint-parity blockers. | PASS | | Example validity checked | JSON Schema validation over all JSON request and response examples returned `examples_checked=476 failures=0`. | PASS | | Description coverage checked | Operation summaries/descriptions, request-body descriptions, parameter descriptions, schema descriptions, and schema property descriptions returned `description_coverage_issues=0`. | PASS | | Tone checked | User-facing OpenAPI prose and v3 introduction copy were normalized toward `~합니다/~습니다`; direct imperative endings were removed from public-facing descriptions. | PASS | | api-server v3 tests checked | Current api-server checkout returns `3 failed, 1113 passed, 18 skipped, 75 warnings`; failures are source-side (`validate-flow-data`, `webhook_version` default, generator count) and are not fixed in this docs PR. | ISSUE | Source-side findings from this pass: * Current api-server generator/audit still need explicit excludes for the 4 confirmed-private flow helper endpoints. The companion api-server PR was closed and removed from scope. * Current api-server `AgentWebhookSettings.webhook_version` has no default, so docs OpenAPI must not publish `webhookVersion.default = "v2"`. * Docs OpenAPI keeps full schema/property descriptions while matching the current source contract after docs-localized `description`/`summary` text is removed. ## Focused Recheck 2026-05-09 Objective restated as concrete deliverables: 1. Spend a focused pass rebuilding the checklist instead of trusting prior results. 2. Check every public API operation one by one. 3. Verify every operation's status codes, request schemas, response schemas, and public/private scope against current api-server source. 4. Check description consistency, natural Korean tone, and developer-friendly wording without over-explaining. 5. Fix docs when the recheck finds drift. Prompt-to-artifact checklist: | Requirement | Evidence | Status | | - | - | - | | Current source regenerated | `ENV=development-ryan uv run python scripts/generate_v3_public_openapi.py --output /tmp/v3-recheck-current-api-server.json ...` returned `paths=45 ops=62 schemas=176 pruned_schemas=16`. | PASS | | Every public operation rechecked | Operation-level script compared all 58 public operations after removing the 4 confirmed-private helper paths. | PASS | | Status codes match source | Operation-level comparison returned `operations_checked=58` and `status_or_schema_mismatches=0` after ignoring localized descriptions. | PASS | | Request and response schemas match source | Full normalized contract comparison returned `docs_ops=58`, `filtered_gen_ops=58`, `docs_schemas=161`, `filtered_gen_schemas=161`, and `normalized contract match`. | PASS | | Docs-side schema drift fixed | Removed stale `webhookVersion.default = "v2"` from `api-reference/v3/openapi.json` because current source has no default. | FIXED | | Operation descriptions complete | Operation scan returned `operation_description_issues=0` across summaries, descriptions, request bodies, parameters, and response descriptions. | PASS | | Schema descriptions complete | Schema/property coverage scan returned `schema_description_issues=0`. | PASS | | Naturalness and tone checked | Public v3 files were scanned for direct imperative/plain-style endings and stale labels; only audit-meta mentions of `TODO`/`ISSUE`/`UNVERIFIED` were found. Human review of all 58 operation summaries/descriptions found the wording concise enough for API reference use. | PASS | | External docs comparison considered | No external docs were needed in this pass because the only concrete drift was against current api-server source; the docs surface already follows the common concise API-reference pattern of summary, short operational description, request/response schema, examples, and error envelope. | PASS | | Source-side issues not hidden | `scripts/v3_audit.py` without ad-hoc excludes still reports exactly 4 known private-helper blockers; `ENV=development-ryan uv run pytest tests/v3 -q` currently fails 3 source-side tests. Both are recorded as source-side issues outside this docs PR. | PASS | ## Completion Audit Concrete objective: make a Markdown checklist, check every endpoint one by one, compare the public docs against current `api-server`, and fix incorrect examples, descriptions, schemas, links, or public/private scope mistakes. | Requirement | Artifact / Evidence | Status | | - | - | - | | Endpoint-by-endpoint checklist exists | This file contains a detailed 58-row public endpoint matrix and a grouped endpoint checklist with 58 public operations plus 4 confirmed-private exclusions. | PASS | | Every public endpoint was individually rechecked | Detailed matrix row count returned 58. No `ISSUE`, `TODO`, or `UNVERIFIED` rows were found in the detailed matrix. | PASS | | Docs OpenAPI has only public v3 endpoints | OpenAPI operation count returned 58. | PASS | | v3 navigation lists exactly the public OpenAPI operations | Recursive `docs.json` v3 nav extraction returned 58 operation entries, matching the OpenAPI operation count. | PASS | | Private helper endpoints stay hidden | Search for the four private helper paths in `docs.json` and `api-reference/v3/openapi.json` returned no matches. | PASS | | Docs OpenAPI matches current api-server source after confirmed-private exclusions | Freshly regenerated api-server OpenAPI produces 62 operations before docs-side filtering. After removing the 4 confirmed-private helpers and pruning unreachable schemas, docs OpenAPI has no contract diff after removing localized `description`/`summary` text. | PASS | | Status codes and operation schemas match current source | Operation-level comparison returned `operations_checked=58` and `status_or_schema_mismatches=0`. | PASS | | Published request and response examples are valid | JSON Schema validation over OpenAPI JSON examples returned `examples_checked=476 failures=0`. | PASS | | Schema descriptions are complete | Coverage check over operations, request bodies, parameters, schemas, and schema properties returned `description_coverage_issues=0`. | PASS | | Public-facing tone is consistent | v3 introduction and OpenAPI descriptions were normalized toward `~합니다/~습니다`; direct imperative endings no longer appear in public-facing v3 prose. | PASS | | Bad v2 examples and stale API reference links are fixed | v3 launch guide pages now point to `/api-reference/v3/introduction`; dynamic variable REST examples use `/v3/calls` and `/v3/campaigns` request shapes. Historical changelog v2 links point to `/api-reference/v2/introduction`. | PASS | | Build and link validation pass | `PATH="/Users/ryanhan/.nvm/versions/node/v20.18.0/bin:$PATH" mint validate` passed. `mint broken-links` passed. | PASS | | Remaining source-side uncertainty is explicitly tracked | `scripts/v3_audit.py` exits 0 only when the 4 confirmed-private helpers are passed as intentional excludes; without them it exits 1 with exactly those 4 endpoint-parity blockers. Current `tests/v3` also has 3 source-side failures outside this docs PR. | PASS | ## Work Log * 2026-05-08: Created checklist in the correct docs submodule. Baseline mismatch: docs OpenAPI 58 operations vs generated api-server public OpenAPI 62 operations. * 2026-05-08: API-side audit of the current docs OpenAPI found 7 blockers: 4 missing public operations, missing `minProperties` on 2 PATCH schemas, and non-integer timestamp fields on schema registry metadata. * 2026-05-08: Initially synced `api-reference/v3/openapi.json` from generated api-server public OpenAPI, then corrected scope after product clarification: `POST /agents/validate-flow-data`, `POST /agents/autofix-flow-data`, `POST /agents/{agent_id}/operations`, and `POST /flow-data/autofix` are not public and were removed from docs OpenAPI/navigation. * 2026-05-08: Scanned guide pages for stale API references. Found and fixed v2 examples in `docs/build/variables/dynamic-variables.mdx` and versionless API reference links in outbound/post-call/export guides. Also clarified that v3 public API has no dedicated CSV export endpoint; programmatic extraction uses `GET /calls` and `GET /calls/{call_id}`. * 2026-05-08: Verified `api-reference/v3/openapi.json` contract matches the expected api-server generated OpenAPI after excluding the four confirmed-private flow helper endpoints, pruning unreachable schemas, and ignoring docs-localized `description`/`summary` text. Verified v3 OpenAPI operations and `docs.json` v3 navigation operations have no diff. * 2026-05-08: Validated public OpenAPI JSON request examples. Result: 12 examples checked, 0 schema validation failures. * 2026-05-08: Checked knowledge ID contract. Public OpenAPI uses numeric integer `knowledge_id` path params and numeric `knowledgeIds` arrays; no UUID wording was found for public knowledge IDs. * 2026-05-08: Patched `scripts/sync-openapi.sh` to enforce docs-side public launch exclusions for the four confirmed-private flow helper endpoints and their private-only schemas. Verified the filter output has 58 operations and matches `api-reference/v3/openapi.json`. * 2026-05-08: Fixed stale changelog links found by validation: `/docs/operate/deploy/cti` now points to the SIP trunking guide, and historical versionless API reference links now point to the v2 API reference. * 2026-05-08: Ran docs validation with Node 20.18 in PATH. `mint validate` passed and `mint broken-links` passed. * 2026-05-08: Added a detailed endpoint-by-endpoint verification matrix with nav/auth/request schema/example count/success response/error envelope/source parity columns for all 58 public operations. Re-generated api-server OpenAPI from current source and confirmed the docs OpenAPI still matches after the four confirmed-private helper endpoints are filtered out. * 2026-05-08: Localized user-facing v3 OpenAPI descriptions in the docs snapshot. Operation descriptions, request-body descriptions, shared error response text, and high-visibility schema descriptions now use Korean prose while preserving code identifiers, enum values, and schema names. Re-verified the contract by stripping `description`/`summary` fields from the docs and filtered generated specs and comparing the normalized JSON. * 2026-05-08: Rebuilt the full verification checklist and re-ran the audit against current `api-server` source. Found one missing coverage class: schema/property descriptions. Added descriptions until the coverage check returned `description_coverage_issues=0`. * 2026-05-08: Source-side recheck exposed api-server v3 test failures: public generator expected 61 ops while current source emitted 62, and `AgentWebhookSettings.webhook_version` default did not match the existing PROD-1493 test. A companion api-server PR was opened briefly, then closed and removed from scope. The docs PR therefore keeps source-side issues tracked rather than patching api-server. * 2026-05-09: Re-generated current api-server OpenAPI after the companion PR was removed: `paths=45 ops=62 schemas=176 pruned_schemas=16`. After docs-side removal of the 4 confirmed-private helper endpoints and unreachable schemas, the filtered source contract has 58 operations and 161 schemas. Docs OpenAPI matches that filtered contract after removing localized `description`/`summary` text. * 2026-05-08: Normalized public-facing v3 prose toward `~합니다/~습니다`. Replaced direct imperative endings in OpenAPI descriptions and the v3 introduction with formal descriptive endings. * 2026-05-09: Removed stale `webhookVersion.default = "v2"` from docs OpenAPI because current api-server source has no default. Re-ran operation-level status code/request schema/response schema comparison for all 58 public operations: `status_or_schema_mismatches=0`. # 스키마 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/schemas/스키마-목록-조회 /api-reference/v3/openapi.json get /schemas API와 MCP 클라이언트가 사용할 수 있는 public JSON Schema 목록을 조회합니다. 스키마 본문까지 받으려면 `include_schema=true`를 사용합니다. # 스키마 조회 Source: https://docs.tryvox.co/api-reference/v3/schemas/스키마-조회 /api-reference/v3/openapi.json get /schemas/{namespace}/{schema_type} namespace, schema type, 선택적 version으로 public JSON Schema 1건을 조회합니다. 설명·제목·예시를 제거한 가벼운 응답이 필요하면 `detail=minimal`을 사용합니다. # 시트 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/sheets/시트-목록-조회 /api-reference/v3/openapi.json get /sheets 행을 불러오지 않고 워크스페이스(`organization_id`)에 속한 아웃바운드 시트 목록을 조회합니다. # 시트 생성 Source: https://docs.tryvox.co/api-reference/v3/sheets/시트-생성 /api-reference/v3/openapi.json post /sheets 아웃바운드 시트와 이를 소유하는 프로젝트를 하나의 작업으로 생성합니다. # 시트 조회 Source: https://docs.tryvox.co/api-reference/v3/sheets/시트-조회 /api-reference/v3/openapi.json get /sheets/{sheet_id} 원본 행을 포함해 워크스페이스(`organization_id`)에 속한 아웃바운드 시트 하나를 조회합니다. # SMS 단건 조회 Source: https://docs.tryvox.co/api-reference/v3/sms/sms-단건-조회 /api-reference/v3/openapi.json get /sms/{sms_id} ID로 단건 SMS 메시지의 상세 정보를 조회합니다. # 발신 SMS 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/sms/발신-sms-목록-조회 /api-reference/v3/openapi.json get /sms 인증된 조직의 발신 SMS를 조회합니다. 귀속된 통화나 Chat, 발신번호·수신번호, 전달 상태, 생성 시각으로 필터링할 수 있습니다. # 수신 SMS 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/sms/수신-sms-목록-조회 /api-reference/v3/openapi.json get /sms/received 인증된 워크스페이스(`organization_id`)의 수신 SMS·MMS 메시지 목록을 조회합니다. 귀속 통화, 발신번호·수신번호, 수신 시각으로 필터링합니다. # SIP 연동 Source: https://docs.tryvox.co/api-reference/v3/telephone-numbers/sip-연동 /api-reference/v3/openapi.json post /telephone-numbers/register vox.ai 외부에서 보유한 custom SIP 전화번호를 등록합니다. 고객이 관리하는 SIP trunk로 라우팅할 번호에 사용합니다. # 전화번호 구매 Source: https://docs.tryvox.co/api-reference/v3/telephone-numbers/전화번호-구매 /api-reference/v3/openapi.json post /telephone-numbers/purchase 인증된 워크스페이스(`organization_id`)에서 사용할 vox.ai 전화번호를 구매합니다. # 전화번호 자원 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/telephone-numbers/전화번호-자원-목록-조회 /api-reference/v3/openapi.json get /telephone-numbers/available 워크스페이스(`organization_id`)가 구매할 수 있는 vox.ai 제공 전화번호 목록을 조회합니다. 구매 요청의 `telephone_line_id`에는 응답의 `id`를 사용합니다. # 발신표기번호 등록 신청 Source: https://docs.tryvox.co/api-reference/v3/telephone-presentation-numbers/발신표기번호-등록-신청 /api-reference/v3/openapi.json post /telephone-presentation-numbers 인증된 워크스페이스(`organization_id`)의 발신번호 표시 등록을 요청합니다. 증빙 서류는 multipart/form-data로 보내세요. pending 상태로 생성되며 심사를 거쳐야 발신번호로 사용할 수 있습니다. rejected 상태의 번호를 재신청하면 새 항목을 만들지 않고 기존 등록에 새 서류를 반영해 pending으로 되돌립니다. # 발신표기번호 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/telephone-presentation-numbers/발신표기번호-목록-조회 /api-reference/v3/openapi.json get /telephone-presentation-numbers 인증된 워크스페이스(`organization_id`)가 수동 등록한 발신표기번호 목록을 조회합니다. 삭제하거나 발신표기번호 부가서비스에 연결할 때 각 항목의 `id`를 사용합니다. # 발신표기번호 삭제 Source: https://docs.tryvox.co/api-reference/v3/telephone-presentation-numbers/발신표기번호-삭제 /api-reference/v3/openapi.json delete /telephone-presentation-numbers/{telephone_presentation_number_id} 인증된 워크스페이스(`organization_id`)의 발신표기번호 등록 레코드를 삭제합니다. 존재하지 않거나 접근할 수 없는 ID는 찾을 수 없는 것으로 처리됩니다. # 도구 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/tools/도구-목록-조회 /api-reference/v3/openapi.json get /tools 인증된 워크스페이스(`organization_id`)에서 사용할 수 있는 custom API 도구 목록을 조회합니다. 목록 응답에는 실행 설정이 생략되며, 자세한 내용은 `GET /v3/tools/{tool_id}`에서 확인합니다. # 도구 삭제 Source: https://docs.tryvox.co/api-reference/v3/tools/도구-삭제 /api-reference/v3/openapi.json delete /tools/{tool_id} 인증된 워크스페이스의 사용자 정의 도구를 삭제하고 에이전트의 현재 초안에서 해당 도구의 참조를 제거합니다. 발행된 버전은 유지됩니다. # 도구 상세 조회 Source: https://docs.tryvox.co/api-reference/v3/tools/도구-상세-조회 /api-reference/v3/openapi.json get /tools/{tool_id} custom 도구 1건을 조회합니다. 입력 스키마와 API 실행 설정을 함께 반환합니다. # 도구 생성 Source: https://docs.tryvox.co/api-reference/v3/tools/도구-생성 /api-reference/v3/openapi.json post /tools 에이전트가 호출할 custom API 도구를 생성합니다. 모델에 노출할 `input_schema`와 서버가 실행할 API 설정을 함께 정의합니다. # 도구 수정 Source: https://docs.tryvox.co/api-reference/v3/tools/도구-수정 /api-reference/v3/openapi.json patch /tools/{tool_id} custom API 도구의 이름, 스키마, 실행 설정, 발화 동작을 수정합니다. # 위젯 게시 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-게시 /api-reference/v3/openapi.json post /widgets/{widget_id}/publish 현재 편집 내용을 새 버전으로 저장하고 인증된 워크스페이스(`organization_id`)의 위젯을 게시합니다. 다시 게시하면 항상 새 버전이 추가됩니다. # 위젯 게시 해제 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-게시-해제 /api-reference/v3/openapi.json post /widgets/{widget_id}/unpublish 인증된 워크스페이스(`organization_id`)의 위젯을 `status=draft`로 바꿔 게시를 해제합니다. 마지막 게시 버전(`published_version_id`)과 `published_at`은 유지됩니다. 게시되지 않은 위젯은 409를 반환합니다. # 위젯 목록 조회 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-목록-조회 /api-reference/v3/openapi.json get /widgets 인증된 워크스페이스(`organization_id`)의 위젯 목록을 조회합니다. `status=archived`를 지정하지 않으면 `archived` 위젯은 제외됩니다. `status`를 반복하면 여러 상태를 함께 조회합니다. # 위젯 삭제 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-삭제 /api-reference/v3/openapi.json delete /widgets/{widget_id} 인증된 워크스페이스(`organization_id`)의 위젯을 `status=archived`로 바꿉니다. 이미 `archived`인 위젯도 204를 반환합니다. # 위젯 생성 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-생성 /api-reference/v3/openapi.json post /widgets `draft` 상태의 위젯을 생성합니다. `public_id`는 서버가 발급합니다. 본문의 `status`와 `published_*`는 무시됩니다. # 위젯 수정 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-수정 /api-reference/v3/openapi.json patch /widgets/{widget_id} 인증된 워크스페이스(`organization_id`)의 위젯을 부분 수정합니다. 본문이 비어 있으면 400, `archived` 위젯은 409를 반환합니다. 본문의 `status`와 `public_id`는 무시됩니다. `branding`을 보내면 모양과 메시지 설정 전체를 교체합니다. # 위젯 조회 Source: https://docs.tryvox.co/api-reference/v3/widgets/위젯-조회 /api-reference/v3/openapi.json get /widgets/{widget_id} 인증된 워크스페이스(`organization_id`)의 위젯 1건을 조회합니다. `archived` 위젯도 조회할 수 있습니다. # 2025년 3월 Source: https://docs.tryvox.co/changelog/2025/03 ## 조건 노드 출시 플로우 에이전트에 조건 노드를 추가했어요. 동적 변수 값에 따라 대화 흐름을 자동으로 나눌 수 있어요. ### 주요 기능 * **자동 노드 전환**: 동적 변수 값에 따라 다음 노드로 자동 전환해요. * **논리 연산자 지원**: 여러 조건을 논리 연산자로 조합할 수 있어요. * **대화 없는 분기**: 고객과 대화하지 않고 내부 로직만으로 분기해요. * **다양한 분기 시나리오**: 시간대별, 고객 유형별, 지역별 분기 시나리오를 만들 수 있어요. [조건 노드 가이드 보기](/docs/build/flow/nodes/condition-node) ## 대시보드 분석 기능 출시 새로운 대시보드 분석 기능이 출시됐어요. 이제 에이전트의 성능과 사용량을 한눈에 파악할 수 있어요. 분석 화면의 총 통화 수, 총 통화 시간, 총 사용 크레딧, 통화 종료 사유, 평균 통화 시간 차트 ### 주요 기능 * **실시간 모니터링**: 총 통화 수와 통화 시간을 실시간으로 볼 수 있어요. * **일별 통계**: 일별 상세 통계와 추이 그래프로 사용 패턴을 분석할 수 있어요. * **크레딧 사용량**: 크레딧 사용량을 추적하고 관리할 수 있어요. * **연결 종료 사유**: 통화가 끝난 사유를 파악해 서비스 개선에 쓸 수 있어요. [대시보드 가이드 보기](/docs/operate/monitor/dashboard) ## 플로우 에이전트 출시 플로우 에이전트가 출시됐어요. 이제 복잡한 대화 흐름을 쉽게 만들고 안정적으로 처리할 수 있어요. ### 주요 기능 * **[노드](/docs/build/flow/nodes/overview)**: 다양한 노드 타입으로 대화 흐름을 세밀하게 설계할 수 있어요. * **[전환 조건](/docs/build/flow/transitions)**: 노드 사이의 전환 조건을 쉽고 명확하게 설정할 수 있어요. * **[글로벌 노드](/docs/build/flow/advanced/global-node)**: 어느 상황에서든 필요한 응답을 준비하고 대화 흐름을 더 정확하게 제어할 수 있어요. * **드래그 앤 드롭 편집**: 노드를 끌어다 놓아 쉽게 배치하고 연결할 수 있어요. [플로우 에이전트 가이드 보기](/docs/build/flow/overview) ## React SDK 출시 Next.js나 React 프로젝트에 음성 AI 에이전트를 쉽게 넣을 수 있는 [@vox-ai/react](https://www.npmjs.com/package/@vox-ai/react) 라이브러리를 출시했어요. ```jsx theme={null} // 사용 예시 const { connect, disconnect, state, messages } = useVoxAI({ onConnect: () => console.log("연결됨"), onMessage: (message) => console.log("새 메시지:", message), }); ``` ### 주요 기능 * **훅 기반 API**: 간단한 훅으로 음성 대화 기능을 만들 수 있어요. * **대화 상태 모니터링**: `listening`, `thinking`, `speaking` 같은 대화 상태를 실시간으로 볼 수 있어요. * **동적 변수 지원**: 동적 변수로 대화를 맞춤화할 수 있어요. * **메타데이터 추적**: 메타데이터로 대화를 분석할 수 있어요. [React SDK 가이드 보기](/docs/sdk/react) # 2025년 4월 Source: https://docs.tryvox.co/changelog/2025/04 ## 전화 대량 발신 출시 한 번에 여러 수신자에게 전화를 거는 전화 대량 발신을 추가했어요. 마케팅, 알림, 설문 조사 같은 목적으로 많은 고객에게 음성 메시지를 전할 수 있어요. ### 주요 기능 * **대량 발신 만들기와 관리**: 새 대량 발신을 만들고, 진행 상황을 지켜보고, 끝난 대량 발신의 결과를 볼 수 있어요. * **수신자 목록 관리**: CSV 파일을 올리거나 직접 입력해 수신자 정보를 한 번에 등록하고 관리할 수 있어요. * **에이전트 연동**: 만든 플로우 에이전트를 대량 발신에 연결해 수신자와의 통화에 쓸 수 있어요. * **발신 일정 설정**: 대량 발신 시작 시간을 예약해 원하는 시간에 자동으로 발신을 시작할 수 있어요. [대량 발신 가이드 보기](/docs/operate/outbound/campaigns) ## 도구 노드와 API 도구 출시 플로우 에이전트에서 외부 도구를 연동하는 도구 노드를 추가했어요. 첫 도구로 API 도구를 쓸 수 있어요. ### 주요 기능 * **[도구 노드](/docs/build/flow/nodes/tool-node)**: 도구를 골라 설정하고 플로우에 넣는 새 노드예요. * **[API 도구](/docs/build/tools/api)**: 도구 노드에서 외부 API를 호출해 데이터를 주고받을 수 있어요. [도구 노드 가이드 보기](/docs/build/flow/nodes/tool-node) ## 통화 전환 노드 출시 전화 통화를 다른 번호로 쉽게 넘길 수 있는 통화 전환 노드를 출시했어요. ### 주요 기능 * **전환 메시지 설정**: 동적 프롬프트로 상황에 맞는 메시지를 만들거나, 정적 프롬프트로 고정 메시지를 설정하거나, 메시지 없이 바로 전환할 수 있어요. * **간편한 번호 설정**: 전화번호만 설정하면 원하는 대상으로 통화를 연결해요. * **글로벌 노드 지원**: 글로벌 노드로 설정해 어느 단계에서든 쓸 수 있어요. [통화 전환 노드 가이드 보기](/docs/build/flow/nodes/transfer-node) ## 동적 변수 추출 노드와 API 노드 출시 플로우 에이전트에서 대화 속 정보를 뽑고 외부 시스템과 연동하는 새 노드를 추가했어요. ### 주요 기능 * **[동적 변수 추출 노드](/docs/build/flow/nodes/extraction-node)**: 대화에서 중요한 정보를 뽑아 변수로 저장해요. 다른 노드에서 `{{변수명}}`으로 참조할 수 있고, 고객 정보 수집, 문의 유형 분류, 키워드 추출에 쓸 수 있어요. * **[API 노드](/docs/build/flow/nodes/api-node)**: 외부 API를 호출해 데이터를 가져오거나 보내요. GET, POST, PUT, DELETE 같은 HTTP 메서드를 지원하고, 동적 변수로 요청 본문을 만들고, 응답 결과에 따라 대화 흐름을 나눌 수 있어요. [노드 개요 가이드 보기](/docs/build/flow/nodes/overview) # 2025년 5월 Source: https://docs.tryvox.co/changelog/2025/05 ## 배경음악과 노이즈 캔슬링 강도 설정 추가 통화 환경을 더 세밀하게 조정할 수 있게 배경음악 설정과 노이즈 캔슬링 강도 조절을 추가했어요. 상황에 맞춰 통화 품질을 맞출 수 있어요. 배경 음악 설정 스크린샷 노이즈 캔슬링 설정 스크린샷 ### 주요 기능 * **배경음악 설정**: 통화 설정에서 통화 중 틀 배경음악을 고를 수 있어요. 사용 안 함, 카페, 사무실, 콜센터, 도서관 같은 옵션으로 더 자연스러운 통화 환경을 만들어요. * **노이즈 캔슬링 강도 조절**: 주변 소음을 지우는 수준을 사용 안 함, 일반 노이즈 캔슬링, 강한 노이즈 캔슬링(다른 사람 목소리 제거) 가운데 고를 수 있어요. [통화 설정 가이드 보기](/docs/build/conversation/call-settings) ## MCP 도구 출시와 통화 API 확장 플로우 에이전트의 외부 시스템 연동을 늘렸어요. MCP(Model Context Protocol) 도구로 Zapier, Composio 같은 외부 서비스와 연동하고, 새 통화 API로 프로그램에서 통화를 제어할 수 있게 됐어요. ### 주요 기능 * **MCP 도구 출시**: Zapier, Composio처럼 MCP를 지원하는 외부 플랫폼과 연동해 이메일 전송, 캘린더 일정 만들기, CRM 업데이트 같은 작업을 에이전트가 직접 처리해요. * **통화 API 확장**: 통화 시작, 종료, 상태 조회 같은 통화 제어를 API로 직접 호출할 수 있게 엔드포인트를 추가했어요. 자체 애플리케이션과 서비스에 음성 AI를 더 긴밀하게 붙일 수 있어요. [API 참조 보기](/api-reference/v3/introduction) ## 에이전트 전환 노드 출시 통화 중에 다른 에이전트로 전환할 수 있는 에이전트 전환 노드를 추가했어요. 상황이나 고객 요구에 맞는 에이전트가 응답을 이어 가게 설정할 수 있어요. ### 주요 기능 * **간편한 전환 설정**: 플로우의 원하는 지점에서 간단한 설정만으로 다른 에이전트에게 통화를 넘길 수 있어요. * **특정 에이전트 버전 선택**: 전환할 에이전트의 버전을 지정할 수 있어 안정적인 운영과 테스트에 쓸모 있어요. [에이전트 전환 노드 가이드 보기](/docs/build/flow/nodes/transfer-agent-node) # 2025년 6월 Source: https://docs.tryvox.co/changelog/2025/06 ## 통화 전환 설정 강화 통화 전환 기능을 더 유연하게 바꿨어요. 여러 전환 대상과 SIP URI 같은 고급 설정으로 통화 전환을 더 정교하게 만들 수 있어요. ### 주요 기능 * **여러 전환 대상 설정**: 전환 도구 하나에 전환 대상을 여러 개 설정해 상황에 맞는 담당자에게 자동으로 연결할 수 있어요. 영업팀, 기술지원팀, 일반 상담팀처럼 대상마다 조건을 따로 정해요. * **SIP URI 지원**: 전화번호 말고도 SIP(Session Initiation Protocol) URI로 전환할 수 있어요. VoIP 시스템이나 내부 통신망과 연동할 때 쓰고, 형식은 `sip:username@domain.com`, `sip:extension@pbx.company.com:5060`이에요. [통화 전환 가이드 보기](/docs/build/tools/builtin/transfer-call) ## 안내 후 전환 추가 AI가 상담사에게 상황을 먼저 전한 뒤 통화를 연결하는 안내 후 전환을 추가했어요. 고객은 상황을 다시 설명하지 않아도 되고, 상담사는 맥락을 파악한 상태에서 응대를 시작해요. 안내 후 전환 설정 스크린샷 ### 주요 기능 * **동적 안내 메시지**: 동적 프롬프트로 안내 메시지를 설정할 수 있어요. * **정적 안내 메시지**: 고정된 안내 메시지를 설정할 수 있어요. * **동적 변수 사용**: 안내 메시지에 `{{customer_name}}` 같은 동적 변수를 넣을 수 있어요. [통화 전환 가이드 보기](/docs/build/tools/builtin/transfer-call) # 2025년 7월 Source: https://docs.tryvox.co/changelog/2025/07 ## 대량 발신 취소 상태 추가 진행 중인 대량 발신을 안전하게 멈출 수 있는 취소 기능을 추가했어요. 대시보드의 대량 발신 상세 페이지나 API로 취소할 수 있어요. ```bash theme={null} curl -X POST "https://client-api.tryvox.co/v2/campaigns/{campaign_id}/cancel" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### 주요 기능 * **새 상태 `canceled`**: 예약됐거나 진행 중인 대량 발신을 취소할 수 있어요. * **선택적 취소**: 대기 중(`pending`) 항목만 취소되고, 진행 중(`ongoing`) 통화는 끝까지 이어져요. * **API 엔드포인트 추가**: `POST /v2/campaigns/{campaign_id}/cancel`로 프로그램에서 취소할 수 있어요. * **통계 호환**: `failed_calls` 지표에 취소된 항목이 포함돼 기존 대시보드와 호환돼요. * **되돌릴 수 없는 상태**: 취소한 대량 발신은 다시 시작하거나 수정할 수 없어요. [전화 대량 발신 가이드 보기](/docs/operate/outbound/call-batch) ## SIP 트렁킹 CTI 통합 출시 기존 전화 시스템(CTI, PBX, VoIP)을 vox.ai와 연결하는 SIP 트렁킹 통합을 출시했어요. 이제 전화번호를 새로 사지 않아도 기존 통신 인프라에서 바로 AI 음성 에이전트를 쓸 수 있게 됐어요. SIP 트렁킹 연결 설정 화면 ### 주요 기능 * **기존 번호 유지**: 지금 쓰는 전화번호를 그대로 쓰면서 AI 에이전트를 운영할 수 있어요. * **시스템 통합**: CTI·PBX 시스템과 통합해 기존 운영 방식을 유지해요. * **간편한 설정**: 번호 관리 페이지에서 SIP 트렁크 정보만 넣으면 바로 연동돼요. * **인바운드·아웃바운드 지원**: 수신과 발신 통화 모두에서 AI 에이전트를 쓸 수 있어요. * **지원 시스템**: Asterisk, FreePBX 같은 오픈소스 PBX, 3CX 같은 클라우드 PBX, Twilio, Telnyx 같은 클라우드 통신 플랫폼처럼 RFC 3261을 따르는 SIP 시스템과 연결할 수 있어요. [SIP 연동 가이드 보기](/docs/operate/deploy/sip-telephony) # 2025년 8월 Source: https://docs.tryvox.co/changelog/2025/08 ## Google TTS 개선 Google의 TTS(Text-to-Speech) 음성 모델 성능을 크게 개선했어요. 정확한 정보 전달이 중요한 고객센터, 금융 상담, 예약 확인 같은 업무에 추천해요. ### 주요 기능 * **200ms대 지연 시간**: 응답 지연 시간이 200ms 수준으로 줄어 실시간에 가까운 자연스러운 대화를 할 수 있어요. * **정확한 숫자·전화번호 발음**: 숫자, 전화번호, 계좌번호를 정확하게 발음해 금융, 상담 업무에 알맞아요. * **공식적인 목소리**: 안정적이고 전문적인 톤이라 공식적인 상황에 알맞아요. [음성 인식과 발화 가이드 보기](/docs/build/voice/voice-select) ## 조건 노드 Else 분기와 API 응답 변수 추출 추가 플로우의 조건 노드와 API 노드 기능을 늘렸어요. API로 재고를 확인한 뒤 재고가 있으면 주문을 진행하고, 없으면 입고 대기를 안내하는 시나리오를 쉽게 만들 수 있어요. ### 주요 기능 * **[Else 분기](/docs/build/flow/nodes/condition-node)**: 조건을 만족하지 않을 때 가는 폴백(fallback) 경로를 설정해 예외 상황을 쉽게 처리할 수 있어요. * **[API 응답 변수 추출](/docs/build/flow/nodes/api-node)**: API 호출 결과를 JSONPath 표현식(`$.data[0].count`, `$.result`)으로 뽑아 변수로 저장하고 다음 노드에서 쓸 수 있어요. * **향상된 조건 로직**: 더 복잡한 비즈니스 로직과 분기를 만들 수 있어요. [조건 노드 가이드 보기](/docs/build/flow/nodes/condition-node) ## 대화 노드 첫 메시지 추가 대화 노드에서 에이전트가 통화를 시작할 때 먼저 말을 거는 첫 메시지를 설정할 수 있게 됐어요. "안녕하세요, 무엇을 도와드릴까요?" 같은 고정 인사가 필요한 인바운드 상담이나 "안녕하세요, \[회사명]입니다" 같은 아웃바운드 통화에 특히 잘 맞아요. ### 주요 기능 * **첫 메시지 고정**: 대화 노드가 동적 프롬프트를 쓸 때도 첫 메시지를 고정해 인사말을 일관되게 유지해요. * **자연스러운 대화 전환**: 첫 메시지 다음에는 동적 프롬프트로 자연스럽게 넘어가 대화를 유연하게 이어 가요. * **지연 시간 단축**: 첫 메시지를 고정하면 LLM 생성 없이 바로 재생돼 응답이 더 빨라져요. * **맞춤형 오프닝**: 상황에 맞는 첫 인사말을 설정해 통화를 더 전문적으로 시작할 수 있어요. [대화 노드 가이드 보기](/docs/build/flow/nodes/conversation-node) ## 결제 시스템 추가 vox.ai에서 크레딧을 직접 충전하고 사용량을 관리할 수 있게 됐어요. 서비스를 멈추지 않고 vox.ai를 계속 쓸 수 있어요. ### 주요 기능 * **카드 등록**: 결제 수단(신용카드, 체크카드)을 안전하게 등록하고 관리할 수 있어요. * **단건 충전**: 필요할 때마다 원하는 금액만큼 크레딧을 충전해요. * **자동 충전**: 크레딧이 일정 금액 아래로 떨어지면 설정한 금액만큼 자동으로 충전해요. * **크레딧 모니터링**: 실시간 크레딧 사용량을 그래프로 보고 사용 내역을 조회할 수 있어요. * **결제 내역**: 상세한 청구 내역과 사용 통계를 볼 수 있어요. [요금 가이드 보기](/docs/start/pricing) # 2025년 9월 Source: https://docs.tryvox.co/changelog/2025/09 ## 대량 발신 고급 기능 추가 대량 발신에 통화 결과 자동 추출, 예약 발신, 발신번호 선택, 실시간 진행 상황 기능을 추가했어요. ### 주요 기능 * **통화 결과 자동 추출**: 통화 중 얻은 정보를 스프레드시트에 자동으로 기록해 후속 작업에 쓸 수 있어요. * **예약 발신**: 원하는 날짜와 시간에 대량 발신이 자동으로 시작되게 예약할 수 있어요. * **발신번호 선택**: 대량 발신을 만들 때 발신에 쓸 발신번호를 고를 수 있어요. * **실시간 진행 상황**: 대량 발신 진행 상태를 실시간으로 보고, 끝나면 상세 통계를 이메일로 자동으로 받아요. [전화 대량 발신 가이드 보기](/docs/operate/outbound/call-batch) ## 대량 발신 출시 한 번에 수백, 수천 명의 고객에게 전화를 걸 수 있는 대량 발신을 출시했어요. 마케팅, 알림, 설문 조사 같은 여러 목적에 쓸 수 있어요. ### 주요 기능 * **Excel·CSV 업로드**: 스프레드시트로 수신자 목록을 관리하고 대량 발신을 진행해요. * **동적 변수 매핑**: 고객 이름, 전화번호 같은 정보를 에이전트 변수에 자동으로 연결해요. * **통화 기록 연동**: 통화마다 결과를 STATUS 셀에서 바로 보고 상세 기록을 조회할 수 있어요. * **여러 시트 지원**: 프로젝트 하나에서 여러 대량 발신 시트를 관리할 수 있어요. [대량 발신 가이드 보기](/docs/operate/outbound/campaigns) ## 도구 페이지 개편 도구 관리 페이지를 새로 정리했어요. ### 주요 기능 * **2패널 레이아웃**: 목록과 상세 화면을 나눠 보여 줘요. * **바로 만들기**: 페이지를 벗어나지 않고 바로 도구를 만들 수 있어요. * **설정 한눈에 보기**: 도구마다 설정을 한눈에 보고 고칠 수 있어요. [도구 개요 가이드 보기](/docs/build/tools/overview) ## 지식 베이스 RAG 자동 제어 추가 지식 베이스 양에 따라 RAG(Retrieval-Augmented Generation)를 자동으로 제어하는 기능을 추가했어요. 지식 베이스 규모와 관계없이 고객에게 정확한 답변을 빠르게 줄 수 있어요. ### 주요 기능 * **자동 지연 시간 최적화**: 지식 베이스 양이 적을 때(10k 토큰 미만)는 프롬프트에 바로 넣어 RAG를 거치지 않고 응답 속도를 높여요. * **대량 지식 베이스 자동 RAG**: 지식 베이스 양이 많을 때(70k 토큰 이상)는 RAG를 자동으로 켜서 알맞은 지식을 검색해 응답해요. * **사용자 선택**: 중간 범위(10k\~70k 토큰)에서는 RAG 사용 여부를 직접 고를 수 있어요. * **실시간 구간 표시**: 지금 지식 베이스의 토큰 양과 해당 구간을 시각적으로 보여 줘요. [지식 베이스 가이드 보기](/docs/build/knowledge/overview) ## 지식 베이스 페이지 개편 지식 베이스 관리 페이지를 새로 정리했어요. ### 주요 기능 * **2패널 레이아웃**: 목록과 상세 화면을 나눠 보여 줘요. * **바로 만들기**: 페이지를 벗어나지 않고 바로 지식 베이스를 만들 수 있어요. * **여러 추가 방식**: 파일 업로드, 웹페이지 크롤링, 텍스트 입력으로 문서를 추가할 수 있어요. * **처리 상태 확인**: 문서 처리 상태를 실시간으로 볼 수 있어요. [지식 베이스 가이드 보기](/docs/build/knowledge/overview) # 2025년 10월 Source: https://docs.tryvox.co/changelog/2025/10 ## 설정 페이지 개편과 계정 연동 추가 설정 페이지를 새로 정리해 워크스페이스와 계정을 더 편하게 관리할 수 있게 됐어요. 구글 계정과 이메일 계정도 자유롭게 연동할 수 있어요. ### 주요 기능 * **통합 설정 구조**: 워크스페이스, 멤버, 프로필, 결제 설정을 한곳에서 보고 관리할 수 있어요. * **일관된 화면**: 모든 설정 페이지를 같은 디자인으로 맞췄어요. * **워크스페이스 멤버 초대**: 이메일로 팀원을 초대하고 역할을 관리할 수 있어요. * **구글 로그인 연동**: 이메일로 가입한 사용자도 구글 계정을 추가로 연결해 두 방법으로 로그인할 수 있어요. * **비밀번호 추가**: 구글로 가입한 사용자도 비밀번호를 설정해 이메일 로그인을 추가할 수 있어요. * **통합 계정 관리**: 프로필 설정에서 연결된 로그인 방법을 모두 보고 관리할 수 있어요. [워크스페이스 설정 가이드 보기](/docs/workspace/settings) ## AI 에이전트 만들기 마법사 출시 이제 복잡한 설정 없이 AI로 에이전트를 만들 수 있게 됐어요. 산업군, 사용 사례, 웹사이트 URL만 넣으면 몇 분 안에 완성된 에이전트를 쓸 수 있어요. 에이전트를 만드는 시간이 1시간에서 1분으로 줄었어요. ### 주요 기능 * **AI 자동 만들기**: 산업군과 사용 사례를 고르면 AI가 그 분야에 맞는 에이전트 프롬프트를 만들어요. * **웹사이트 기반 만들기**: 회사 웹사이트 URL을 넣으면 AI가 사이트 정보를 분석해 비즈니스에 맞는 에이전트를 제안해요. * **템플릿 라이브러리**: 산업별 템플릿으로 빠르게 시작할 수 있어요. * **단계별 안내**: 전체 화면 마법사가 에이전트를 만드는 과정을 단계별로 안내해요. [시작하기 가이드 보기](/docs/start/quickstart) ## 변수 패널 출시 플로우 에이전트에서 변수를 더 쉽게 관리하는 변수 패널을 추가했어요. 복잡한 플로우에서도 변수를 쉽게 관리하고 실수를 줄일 수 있어요. ### 주요 기능 * **변수 분류**: 시스템 변수, 사용자 정의 변수, API 응답 변수를 카테고리별로 나눠 보여 줘요. * **빠른 검색**: 필요한 변수를 실시간 검색으로 바로 찾을 수 있어요. * **변수 강조**: 모든 입력 칸에서 `{{변수}}` 구문을 색으로 강조해 변수 사용을 한눈에 볼 수 있어요. * **한눈에 보기**: 쓸 수 있는 변수를 모두 한곳에서 보고 복사해 쓸 수 있어요. [동적 변수 가이드 보기](/docs/build/variables/dynamic-variables) # 2025년 11월 Source: https://docs.tryvox.co/changelog/2025/11 ## 통화 상세 공유와 통화 기록 화면 개선 통화 내용을 더 쉽게 공유하고 통화 기록을 더 편하게 볼 수 있게 화면을 개선했어요. ### 주요 기능 * **외부 공유용 통화 상세 페이지**: 통화 내용을 외부에 안전하게 공유하는 전용 페이지를 추가했어요. * **모바일 대응 강화**: 통화 기록 화면의 모바일 사용성과 재생 경험을 개선했어요. * **[조건 노드 연산자 확장](/docs/build/flow/nodes/condition-node)**: `EXISTS`, `DOES_NOT_EXIST` 조건을 쓸 수 있어요. * **폴더 관리 개선**: 에이전트 폴더 복제와 정리가 더 쉬워졌어요. [통화 기록 가이드 보기](/docs/operate/monitor/history) ## gpt-oss-120b 모델과 에이전트 기능 추가 LLM 모델 `gpt-oss-120b`를 추가하고, 에이전트 전환 노드와 추출 노드의 설정을 늘렸어요. ### 주요 기능 * **gpt-oss-120b**: 음성 입력부터 응답까지 평균 0.2초가 걸려요. LLM 추론 강도도 설정할 수 있어요. * **[에이전트 전환 노드](/docs/build/flow/nodes/transfer-agent-node)**: 전환할 때 대화 내용을 보존하는 옵션을 추가했어요. * **[추출 노드](/docs/build/flow/nodes/extraction-node)**: 노드마다 LLM을 따로 설정할 수 있어요. [노드 개요 가이드 보기](/docs/build/flow/nodes/overview) # 2025년 12월 Source: https://docs.tryvox.co/changelog/2025/12 ## GLM-4.7 모델 추가 빠른 응답이 필요한 음성 에이전트에 쓸 수 있는 LLM 모델 GLM-4.7을 추가했어요. 에이전트 설정에서 골라 쓸 수 있어요. ## 통화 전환 설정 개선 통화를 다른 번호나 시스템으로 넘기는 시나리오를 더 유연하게 구성할 수 있게 개선했어요. ### 주요 기능 * **전화번호·SIP 주소 전환 지원**: 일반 전화번호와 SIP 주소를 모두 전환 대상으로 쓸 수 있어요. * **전환 타입 선택**: 상황에 맞게 통화 전환 방식을 고를 수 있어요. * **발신자 표시 번호 설정**: 전환할 때 상대방에게 보일 번호를 세밀하게 정할 수 있어요. * **안내 메시지와 SIP 헤더 설정**: 연결 전 안내와 전화 시스템 연동을 더 쉽게 구성할 수 있어요. [통화 전환 가이드 보기](/docs/build/tools/builtin/transfer-call) ## gpt-5.2 모델 추가 OpenAI의 새 LLM 모델 `gpt-5.2`를 추가했어요. 에이전트 설정에서 골라 쓸 수 있어요. ## 통화 비용 정보 개선 통화 비용을 더 명확하게 확인할 수 있게 관련 정보를 개선했어요. ### 주요 기능 * **비용 정보 강화**: 통화 비용 상세 내역을 더 명확하게 볼 수 있어요. [통화 기록 가이드 보기](/docs/operate/monitor/history) # 2026년 1월 Source: https://docs.tryvox.co/changelog/2026/01 ## 대량 발신 운영 기능 강화 대량 발신을 더 안전하고 유연하게 운영할 수 있게 제어 기능을 늘렸어요. ### 주요 기능 * **발신 허용 시간대 설정**: 원하는 시간대에만 대량 발신이 동작하게 설정할 수 있어요. * **일시정지·재개·중단 지원**: 진행 중인 대량 발신을 상황에 맞게 직접 제어할 수 있어요. * **운영 시간 안전장치**: 허용 시간 밖의 발신을 막아 실수를 줄여요. * **대량 발신 이력 개선**: 시트에서 실행한 대량 발신 이력을 더 편하게 볼 수 있어요. [전화 대량 발신 가이드 보기](/docs/operate/outbound/call-batch) # 2026년 2월 Source: https://docs.tryvox.co/changelog/2026/02 ## 통화 기록과 에이전트 버전 확인 기능 개선 통화 상태와 에이전트 버전 정보를 더 빨리 확인할 수 있게 모니터링 화면을 개선했어요. ### 주요 기능 * **에이전트 버전 선택 개선**: 프로덕션 버전 선택과 버전 검색이 더 편해졌어요. * **통화 상세 정보 강화**: 비용, 상태, 번호 복사, 에이전트 ID 같은 핵심 정보를 더 쉽게 볼 수 있어요. * **대량 발신 결과 내보내기**: CSV 내보내기와 비용 컬럼을 지원해 결과를 더 편하게 정리할 수 있어요. * **통화 실패 사유 표시 강화**: 연결 실패 원인을 더 자세히 나눠 보여 줘요. [통화 기록 가이드 보기](/docs/operate/monitor/history) ## LLM 상태 자동 점검과 자동 라우팅 개선 여러 LLM 제공자의 응답 속도와 안정성을 주기적으로 점검하고, 더 빠르고 안정적인 모델을 자동으로 먼저 고르도록 개선했어요. ### 주요 기능 * **응답 속도와 안정성 자동 점검**: 여러 LLM 제공자의 상태를 주기적으로 측정해요. * **자동 모델 선택**: 같은 모델 그룹 안에서 더 빠르고 안정적인 모델을 자동으로 먼저 써요. * **장애 대응 강화**: 일시적으로 느리거나 실패하는 경로는 자동으로 우회해요. ## 알림 규칙과 알림 기록 추가 운영 문제를 더 빨리 감지하고 대응할 수 있게 알림 기능을 추가했어요. ### 주요 기능 * **알림 규칙 관리**: 조건, 임계값, 대상을 더 직관적으로 설정할 수 있어요. * **알림 기록 확인**: 알림 발생 이력과 상태를 기록해 운영 문제를 체계적으로 관리할 수 있어요. * **여러 채널로 알림 전송**: 이메일, Slack, 웹훅 같은 채널로 알림을 받을 수 있어요. * **분석 정보 강화**: 평가 로그, 알림 통계, 추세 정보를 한 화면에서 볼 수 있어요. [알림 가이드 보기](/docs/operate/monitor/alerts) ## 웹훅 설정 추가 외부 시스템 연동을 더 쉽게 구성할 수 있게 웹훅 설정을 추가했어요. ### 주요 기능 * **웹훅 URL 설정**: 워크스페이스에서 쓸 웹훅 URL을 설정할 수 있어요. * **웹훅 서명 키 관리**: **설정 > 웹훅**에서 웹훅 서명 키를 만들고, 다시 만들고, 삭제할 수 있어요. [웹훅 가이드 보기](/docs/operate/monitor/webhooks/overview) # 2026년 3월 Source: https://docs.tryvox.co/changelog/2026/03 ## vox.ai 전화번호 직접 발급과 통신료·AI 사용료 통합 청구 외부 통신사와 따로 계약하지 않아도 vox.ai 대시보드에서 전화번호를 바로 발급받을 수 있게 됐어요. 통신료와 AI 사용료도 vox.ai 한 곳에서 함께 청구해 요금 관리가 단순해졌어요. ### 주요 기능 * **[vox.ai 전화번호 직접 발급](/docs/operate/deploy/phone-numbers)**: **배포 > 전화번호**에서 전화번호를 바로 사서 발급받고 에이전트에 연결할 수 있어요. * **[통신료·AI 사용료 통합 청구](/docs/start/pricing)**: 통화 중 생기는 통신료와 음성 인식, LLM, 음성 합성 사용료를 모두 vox.ai 인보이스로 합쳐 청구해요. * **인보이스 발행**: **설정 > 결제**에서 이번 달 결제 예정 금액을 미리 볼 수 있어요. 전월 사용량을 기준으로 다음 달 5일에 인보이스가 발행되고 10일에 결제돼요. [전화번호 가이드 보기](/docs/operate/deploy/phone-numbers) ## 대량 통화 기록 내보내기와 SIP 발신 경로 정리 통화 기록을 많이 내보낼 때도 결과를 기다리지 않고 다른 작업을 이어 갈 수 있게 됐어요. 외부 SIP 트렁크로 나가는 발신 경로도 하나로 정리해 발신 품질이 더 안정적으로 유지돼요. ### 주요 기능 * **[대량 통화 기록 내보내기](/docs/operate/monitor/exports)**: 내보낼 기록이 많아도 화면을 닫거나 다른 작업을 이어 가도 돼요. 파일이 준비되면 알림 배지와 메시지로 알려요. * **[SIP 트렁크 발신 경로 정리](/docs/operate/deploy/sip-telephony)**: 고객이 연결한 SIP 트렁크로 나가는 발신도 vox.ai 전화 시스템을 거치게 통일해 발신 품질이 일관되게 유지돼요. [내보내기 가이드 보기](/docs/operate/monitor/exports) ## 음성 인식 설정 개선과 DTMF 전송 도구 추가 음성 인식 설정을 더 세밀하게 조정하고, 통화 중 키패드 입력이 필요한 시나리오도 더 쉽게 만들 수 있게 됐어요. ### 주요 기능 * **음성 인식 속도 설정**: 상황에 맞게 음성 인식 속도를 직접 조정할 수 있어요. * **다국어 지원**: 여러 언어를 쓰는 통화에서도 음성을 더 자연스럽게 인식해요. * **[DTMF 전송 도구](/docs/build/tools/builtin/send-dtmf)**: 에이전트가 통화 중 숫자 키패드를 눌러 안내 메뉴를 따라갈 수 있어요. [DTMF 전송 가이드 보기](/docs/build/tools/builtin/send-dtmf) # 2026년 4월 Source: https://docs.tryvox.co/changelog/2026/04 ## 차단 번호 관리, 대량 발신 자동 재발신, 문자 이미지 첨부 워크스페이스 단위로 통화를 거부할 번호를 관리하고, 연결되지 않은 통화를 자동으로 다시 걸 수 있게 됐어요. 문자 발신 도구와 문자 발신 노드에서 이미지도 첨부할 수 있게 됐어요. ### 주요 기능 * **[차단 번호 관리](/docs/operate/deploy/blocked-numbers)**: **설정 > 차단 번호**에서 수신·발신 차단 번호를 등록하고 관리할 수 있어요. 번호마다 적용 범위(전체·특정 번호선)와 차단 방향(수신·발신·양방향)을 정하고, CSV·Excel 파일로 여러 건을 한 번에 올리거나 지금 목록을 내려받을 수 있어요. * **[대량 발신 자동 재발신](/docs/operate/outbound/call-batch#미연결-건-다시-걸기)**: 대량 발신이 끝난 뒤 미연결 건을 자동으로 다시 걸어요. 재시도 횟수(최대 3회)와 다시 걸 종료 사유를 대량 발신을 만들 때 정해 두면, 운영자가 챙기지 않아도 정한 횟수만큼 다시 걸어요. * **[문자 이미지 첨부](/docs/build/tools/builtin/send-sms)**: **발신 > 문자**, 문자 발신 도구, [문자 발신 노드](/docs/build/flow/nodes/send-sms-node)에서 정적 모드로 쓸 때 이미지(JPG·PNG·WebP)를 최대 3장까지 첨부해 MMS로 보낼 수 있어요. * **[발신번호 선택](/docs/build/tools/builtin/send-sms)**: 문자를 보낼 수 있는 번호가 여러 개인 워크스페이스에서는 문자 발신 도구, 문자 발신 노드, **발신 > 문자**에서 발신번호를 직접 고를 수 있어요. [차단 번호 가이드 보기](/docs/operate/deploy/blocked-numbers) ## v3 API 공개 v3 API 참조를 공개했어요. 에이전트 만들기, 통화 조회, 대량 발신 실행, 번호 관리처럼 자주 쓰는 작업을 도메인별로 정리하고, 응답 형식과 오류 처리 방식을 일관되게 맞춰 외부 도구와 SDK 연동을 안정적으로 만들 수 있어요. ### 주요 기능 * **[v3 API 참조](/api-reference/v3/introduction)**: 에이전트, 통화, 대량 발신, 전화번호, 도구, 알림, 지식 베이스, 모델 API를 작업 단위로 볼 수 있어요. * **[데이터 구조 확인](/api-reference/v3/introduction#스키마-레지스트리)**: 에이전트 설정, 플로우 데이터, 기본 도구의 필드 구조를 API에서 확인해 내부 도구나 SDK를 만들 때 실수를 줄여요. * **기존 v2 연동 유지**: 공개할 때 기존 v2 API 참조도 함께 유지했어요. 새 연동은 v3로 시작하는 것을 권장해요. [API 참조 보기](/api-reference/v3/introduction) ## 발신표기번호 직접 등록과 AI 앱 플러그인 베타 출시 상대방에게 보이는 발신번호를 대시보드에서 직접 등록할 수 있게 됐어요. Claude Code 같은 AI 코딩 도구에서 vox.ai 에이전트를 바로 다루는 플러그인도 함께 출시했어요. ### 주요 기능 * **[발신표기번호 직접 등록](/docs/operate/deploy/phone/caller-id)**: 번호 상세 화면에서 발신표기번호를 바로 신청하고 등록할 수 있어요. 등록한 번호는 그 뒤 발신할 때 상대방에게 그대로 보여요. * **[AI 앱 플러그인 베타](/docs/ai/overview)**: Claude Code, OpenAI Codex, Claude Cowork에 vox.ai 플러그인을 설치하면 에이전트 만들기, 문서 조회, 운영 작업을 간단한 명령으로 처리할 수 있어요. * **통화 한도 도달 이메일 알림**: 일·시간 한도를 넘어 발신이 막히면 워크스페이스 관리자에게 바로 이메일로 알려요. [발신표기번호 가이드 보기](/docs/operate/deploy/phone/caller-id) ## 문자 발신 도구와 문자 발신 노드 출시 에이전트가 통화 흐름에 맞춰 직접 문자를 보낼 수 있게 됐어요. 플로우 중간에 문자 발신 단계를 넣거나, 통화 중 상황에 따라 에이전트가 스스로 판단해 문자를 보내요. ### 주요 기능 * **[문자 발신 도구](/docs/build/tools/builtin/send-sms)**: 통화 중 에이전트가 상황을 판단해 직접 문자를 보내는 도구예요. "주소를 문자로 보내주세요" 같은 요청에 에이전트가 바로 응답해요. * **[문자 발신 노드](/docs/build/flow/nodes/send-sms-node)**: 플로우 중간에 문자 발신 단계를 넣을 수 있어요. 특정 노드를 지날 때 안내 문자를 자동으로 보내거나, 통화가 끝난 뒤 예약 확인 메시지를 보내는 데 쓸 수 있어요. [문자 발신 가이드 보기](/docs/build/tools/builtin/send-sms) ## 공식 문서 구조 개편 vox.ai 공식 문서의 내비게이션을 탭 기반으로 새로 정리했어요. 시작하기, 빌드, 운영, API, SDK, AI 탭으로 나눠 필요한 문서를 더 빨리 찾을 수 있어요. # 2026년 5월 Source: https://docs.tryvox.co/changelog/2026/05 ## 보이스 클론 출시 워크스페이스 전용 비공개 보이스를 직접 만들 수 있게 됐어요. 짧은 음성 샘플 하나로 브랜드 톤이나 특정 인물의 발성을 담은 보이스를 에이전트에 연결해요. ### 주요 기능 * **[보이스 클론](/docs/build/voice/voice-clone)**: 보이스 라이브러리에서 녹음하거나 음성 파일을 올려 비공개 보이스를 만들 수 있어요. * **이용 정책 동의 필수**: 보이스 클론을 만들려면 그 음성을 쓸 권리나 명시적 동의가 있어야 하고, [vox.ai 이용 정책](https://tryvox.co/legal/use-policy)을 지켜야 해요. [보이스 클론 가이드 보기](/docs/build/voice/voice-clone) ## 레터링 직접 신청·해지와 Cartesia 음성 설정 개선 번호 관리에서 레터링을 직접 신청하고 같은 화면에서 상태를 볼 수 있게 됐어요. 사용 중인 레터링은 대시보드나 API에서 해지하고, 필요하면 해지 요청을 철회할 수 있어요. Cartesia 음성에는 sonic-3.5를 적용해 속도와 볼륨 설정이 더 안정적으로 반영돼요. ### 주요 기능 * **[레터링 신청](/docs/operate/deploy/phone/lettering)**: 전화번호나 승인된 발신표기번호 상세에서 상품을 고르고, 수신자 화면에 보일 업체명을 적어 신청할 수 있어요. * **상태 확인**: 신청 중, 서류 확인 중, 승인 완료, 사용 중, 해지 요청 상태를 번호 상세에서 볼 수 있어요. * **해지와 해지 철회**: 사용 중인 레터링은 해지할 수 있고, 해지 요청 상태에서는 철회할 수 있어요. * **API로 레터링 관리**: 자체 운영 도구에서도 레터링 신청, 해지, 해지 철회 흐름을 연결할 수 있어요. * **Cartesia 음성 설정 개선**: Cartesia sonic-3.5 음성에서 발화 속도와 볼륨 설정이 더 안정적으로 적용돼요. [레터링 가이드 보기](/docs/operate/deploy/phone/lettering) ## 통화 종료와 분석 결과를 나눈 웹훅 v2 공개 통화 종료 알림을 먼저 받고, 요약, 감정 분석, 추출 결과, 비용은 준비되는 대로 따로 받을 수 있게 됐어요. CRM 업데이트, 알림 전송, 비용 집계를 서로 기다리지 않고 처리할 수 있어요. 기존 v1 연동은 그대로 유지돼요. ### 주요 기능 * **[빠른 종료 처리](/docs/operate/monitor/webhooks/schema)**: 웹훅 v2의 `call_ended`에서 종료 상태, 스크립트, 녹음 URL을 받아 후속 작업을 바로 시작해요. * **분석 결과 분리**: 요약, 감정 분석, 추출 결과, 비용은 `call_analyzed`에서 따로 받아요. * **기존 연동 유지**: 기존 v1 수신 서버는 그대로 쓰고, 새 연동은 v2로 시작할 수 있어요. * **후속 작업 분리**: 통화 종료 알림은 CRM 업데이트와 알림 전송에, 분석 결과는 리포트와 비용 집계에 나눠 써요. [웹훅 가이드 보기](/docs/operate/monitor/webhooks/overview) ## 번호별 A/B 테스트와 플로우 에이전트 작성 지원 한 전화번호에 여러 에이전트 버전을 연결할 수 있게 됐어요. 새 버전은 일부 통화에만 먼저 적용하고 결과를 보며 비율을 높이고, 문제가 있으면 안정 버전으로 되돌려요. Claude Code, Codex, Claude Cowork에서 [플로우 에이전트](/docs/build/flow/overview)를 만들 때도 저장 전 검증으로 실수를 줄일 수 있어요. ### 주요 기능 * **[번호별 A/B 테스트](/docs/operate/monitor/ab-testing)**: 한 번호의 인바운드와 아웃바운드 통화를 여러 버전으로 나눠 비교할 수 있어요. * **점진적 배포**: 새 버전에 10%만 배정하고 실제 통화 결과를 보며 늘릴 수 있어요. * **빠른 롤백**: 안정 버전 비율을 100%로 되돌리면 새 통화부터 바로 반영돼요. * **[플로우 에이전트 작성 지원](/docs/build/flow/overview)**: Claude Code, Codex, Claude Cowork에서 만든 플로우를 저장하기 전에 구조 오류와 빠진 전환을 확인해요. [A/B 테스트 가이드 보기](/docs/operate/monitor/ab-testing) # 2026년 6월 Source: https://docs.tryvox.co/changelog/2026/06 ## 하위 워크스페이스 출시 상위 워크스페이스 아래에 별도 워크스페이스를 만들 수 있게 됐어요. 고객사별, 부서별, 브랜드별로 멤버와 번호, 에이전트를 나누고 요금은 상위 워크스페이스 한 곳으로 모아요. ### 주요 기능 * **[하위 워크스페이스](/docs/workspace/sub-organizations)**: 상위 워크스페이스 아래에 별도 워크스페이스를 만들어 고객사·부서·브랜드 단위로 운영할 수 있어요. * **청구 합산**: 하위 워크스페이스의 사용 요금과 구독 기준은 상위 워크스페이스를 따라요. * **멤버와 리소스 분리**: 하위 워크스페이스마다 멤버, 전화번호, 에이전트, API 키를 따로 관리할 수 있어요. * **인증 위임**: 하위 워크스페이스의 워크스페이스 인증은 상위 워크스페이스가 대신 신청할 수 있어요. [하위 워크스페이스 가이드 보기](/docs/workspace/sub-organizations) ## 인바운드 웹훅 서명 검증 추가 통화 시작 전에 CRM이나 내부 시스템에서 고객 정보를 받아 오는 인바운드 웹훅에 HMAC-SHA256 서명을 적용할 수 있게 됐어요. 요청이 vox.ai에서 왔는지 검증한 뒤 고객 정보를 돌려줄 수 있어 외부 연동을 더 안전하게 운영할 수 있어요. ### 주요 기능 * **[인바운드 웹훅 서명](/docs/build/variables/inbound-webhook#hmac-서명-검증-선택)**: 에이전트 설정에서 인바운드 웹훅 서명을 켜면 요청에 서명 헤더가 붙어요. * **워크스페이스 서명 키 사용**: **설정 > 웹훅**에서 발급한 서명 키를 통화 데이터 웹훅과 인바운드 웹훅에 함께 쓸 수 있어요. [인바운드 웹훅 가이드 보기](/docs/build/variables/inbound-webhook) ## 대시보드 홈 개편 대시보드 홈에서 운영 지표를 더 빠르게 볼 수 있게 됐어요. 통화, 문자, 정보 추출, A/B 테스트 지표를 탭으로 나누고 기간 필터와 차트를 함께 정리해 워크스페이스 상태를 한 화면에서 볼 수 있어요. ### 주요 기능 * **운영 지표 탭 분리**: 통화, 문자, 정보 추출, A/B 테스트 지표를 목적별로 나눠 볼 수 있어요. * **기간별 추이 확인**: 고른 기간에 맞춰 통화량, 비용, 응답 지연, 종료 사유 같은 주요 지표를 차트로 볼 수 있어요. * **정보 추출 결과 확인**: 통화 후 추출된 항목의 입력률과 결과를 대시보드 홈에서 바로 볼 수 있어요. [대시보드 가이드 보기](/docs/operate/monitor/dashboard) # 2026년 7월 Source: https://docs.tryvox.co/changelog/2026/07 ## 고객·메모리 출시 에이전트가 대화 상대를 기억하게 됐어요. 전화·채팅 상대를 사람 단위 고객으로 정리하고, 대화에서 확인한 사실을 메모리로 저장했다가 같은 고객이 다시 연락하면 맥락을 이어 응대해요. 단골 응대, 예약 확인, 반복 상담처럼 같은 고객이 여러 번 연락하는 경우에 특히 잘 맞아요. ### 주요 기능 * **[고객](/docs/operate/monitor/customers)**: 채널별 대화 상대를 고객으로 자동 정리해요. CRM 고객 ID나 방문자 ID를 넘기면 자체 시스템의 고객과 연결할 수 있어요. * **[메모리](/docs/build/customer-memory/memory)**: 대화가 끝나면 기억할 만한 사실을 뽑아 저장하고, 같은 고객과 다음 대화를 시작할 때 에이전트에게 전해요. * **[고객 속성](/docs/build/customer-memory/attributes)**: 멤버십 등급, 관심 상품처럼 워크스페이스가 정한 항목에 맞춰 대화에서 값을 자동으로 뽑아요. * **[API로 고객 데이터 관리](/api-reference/v3/introduction)**: v3 API와 vox CLI로 고객 조회, 병합, 삭제와 메모리 관리를 자동화할 수 있어요. [고객 메모리 가이드 보기](/docs/build/customer-memory/overview) ## 데이터 보존 정책 출시와 최대 통화 시간 종료 개선 에이전트별 보안 설정에서 통화와 채팅 콘텐츠의 보존 정책을 정할 수 있게 됐어요. 보존 기간과 저장할 데이터를 함께 골라 통화 녹음, 스크립트, 분석 결과 가운데 필요한 항목만 보관하고, 이 설정이 기존의 민감한 데이터 저장 금지 설정을 대신해요. 최대 통화 시간에 가까워진 통화도 종료 안내와 마지막 인사를 거쳐 자연스럽게 끝나요. ### 주요 기능 * **[데이터 보존 정책](/docs/build/security/data-retention)**: 보안 설정에서 **보존 기간**과 **저장할 데이터**를 함께 정해요. 보존 기간은 즉시 삭제, 무기한, 기간 지정 가운데 골라요. * **[통화 데이터 저장 제외](/docs/build/security/data-opt-out)**: 통화 녹음만 저장하지 않거나, 즉시 삭제로 통화가 끝난 뒤 콘텐츠를 지우게 설정할 수 있어요. * **[자연스러운 통화 종료](/docs/build/conversation/call-settings#통화-길이-관리하기)**: 최대 통화 시간이 다가오면 종료를 안내하고 고객의 마지막 응답을 기다린 뒤 마지막 인사로 통화를 끝내요. [데이터 보존 정책 가이드 보기](/docs/build/security/data-retention) ## 대표번호 구매 추가 수신자에게 익숙한 전국대표번호를 vox.ai에서 직접 살 수 있게 됐어요. 대표번호 하나로 수신과 발신을 함께 운영할 수 있어요. ### 주요 기능 * **[대표번호 구매](/docs/operate/deploy/phone-numbers#번호-준비하기)**: **배포 > 전화번호** 목록 위의 **+** 버튼에서 **대표번호 구매**를 고르고, 살 수 있는 번호 목록에서 원하는 번호를 신청해요. 구매하려면 착신용 활성 070 번호가 1개 이상 있어야 해요. * **수신과 발신 모두 활용**: 대표번호로 걸려 온 전화는 착신 070 번호에 등록된 에이전트가 받아요. 발신할 때는 대표번호를 발신표기번호로 표시할 수 있어요. * **[레터링으로 연결률 향상](/docs/operate/deploy/phone/lettering)**: 대표번호에 레터링을 신청하면 발신할 때 수신자 화면에 업체명이 보여 아웃바운드 통화 연결률을 높일 수 있어요. [전화번호 가이드 보기](/docs/operate/deploy/phone-numbers) ## vox CLI 출시 터미널에서 에이전트를 만들고, 검증하고, 배포하는 vox CLI를 공개했어요. 에이전트 정의가 JSON 파일로 프로젝트에 남아 코드처럼 리뷰하고 롤백할 수 있어요. Claude Code, Codex 같은 코딩 에이전트에 에이전트 제작을 맡길 때도 CLI가 표준 경로예요. ### 주요 기능 * **[CLI 설치와 시작](/docs/ai/cli)**: npm이나 Homebrew로 설치하고 `vox auth login`으로 바로 시작할 수 있어요. * **에이전트를 코드처럼 관리**: `agent.json`을 고치고 `doctor`, `validate`, `diff`, `push`로 저장 전 검증부터 배포까지 터미널에서 처리할 수 있어요. * **[코딩 에이전트 연동](/docs/ai/clients)**: `vox init` 한 번으로 Claude Code와 Codex가 인식하는 스킬이 프로젝트에 생겨요. * **플러그인·MCP 지원 종료**: 기존 AI 앱 플러그인과 MCP 연동은 vox CLI로 바뀌었어요. 새 연동은 CLI를 쓰세요. [CLI 가이드 보기](/docs/ai/cli) # 2026년 8월 Source: https://docs.tryvox.co/changelog/2026/08 ## 웹사이트 위젯 출시 전화 응대에 쓰던 에이전트를 웹사이트 상담 창으로 연결할 수 있게 됐어요. 방문자는 사이트를 떠나지 않고 에이전트와 대화해요. ### 주요 기능 * **[웹사이트 상담 창 연결](/docs/operate/deploy/widget/overview)**: **배포 > 위젯**에서 에이전트를 고르고 코드 한 줄을 웹페이지에 붙이면 위젯이 설치돼요. * **[세 가지 상담 방식](/docs/operate/deploy/widget/modes)**: 채팅 상담, 브라우저 음성 통화, 방문자가 남긴 전화번호로 에이전트가 다시 거는 전화 요청 가운데 하나를 골라요. * **[맞춤 디자인](/docs/operate/deploy/widget/appearance)**: 웹사이트 스타일에 맞춰 위젯의 색, 위치, 첫 인사말을 바꿀 수 있어요. [위젯 가이드 보기](/docs/operate/deploy/widget/overview) ## 안내 후 전환 통화 기록 개선 상담사에게 통화를 넘긴 뒤 고객과 나눈 대화까지 통화 전체를 기록하게 됐어요. 통화가 끝날 때까지 모든 대화가 녹음과 화자 구분 스크립트로 남아요. ### 주요 기능 * **[상담사 대화 기록](/docs/build/tools/builtin/transfer-call)**: 에이전트가 상담사에게 상황을 전하고 연결한 뒤 고객과 나눈 대화까지 모두 기록해요. * **[통화 기록에서 이어 듣기](/docs/operate/monitor/history)**: 통화 기록 상세에서 에이전트 응대 구간과 상담사 응대 구간을 한 플레이어로 이어 듣고 스크립트를 볼 수 있어요. * **요금 유지**: 통화 전체를 기록해도 이용 요금은 달라지지 않아요. [통화 기록 가이드 보기](/docs/operate/monitor/history) ## 에이전트 템플릿 추가 에이전트 템플릿이 12종에서 25종으로 늘었어요. 업종에 가까운 템플릿을 골라 에이전트를 만들고 바로 테스트 통화를 걸 수 있어요. ### 주요 기능 * **고객 문의와 예약 접수**: 병원 리셉션, 식당 예약, 호텔 컨시어지, 부동산 관리, 가전 AS 접수, 주문 배송 조회 템플릿이 있어요. * **영업과 고객 유치**: 프로모션 세일즈, 기업 상담 검증, 인테리어 시공 접수, 해지 고객 재유치 템플릿이 있어요. * **안내와 설문 수집**: 예약 확인, 정기검진 안내, 이용 만족도 조사, 피드백 수집, 미수금 회수 템플릿이 있어요. [시작하기 가이드 보기](/docs/start/quickstart) ## 주소 검색 도구 출시 통화 중 고객이 말한 주소를 검색해 도로명 주소나 지번 주소로 확정하는 도구를 추가했어요. 배송지나 방문지를 전화로 접수하는 업무에 쓸 수 있어요. ### 주요 기능 * **[주소 검색 도구 연결](/docs/build/tools/builtin/search-address)**: 에이전트 설정의 도구에서 추가하면 바로 통화에 적용돼요. * **정확한 주소 확인**: 동 이름이 겹치거나 건물명만 말해도 후보를 찾아 고객에게 확인한 뒤 주소를 확정해요. [주소 검색 가이드 보기](/docs/build/tools/builtin/search-address) ## 통화 스크리닝 대응 출시 발신 통화를 상대방 스마트폰의 AI 통화비서가 대신 받을 때 에이전트가 발신 목적을 남길 수 있게 됐어요. 수신자는 남은 안내를 보고 전화를 받을지 정해요. ### 주요 기능 * **[발신 통화 스크리닝 대응](/docs/build/conversation/call-settings)**: 통화 설정에서 기능을 켜면 AI 통화비서 응대에 맞춰 준비한 목적 안내를 전해요. * **응답 방식 선택**: 고정 문구를 전하거나 지시문을 바탕으로 통화마다 알맞은 응답을 만들어요. * **응답 후 통화 종료**: 발신 목적만 남기고 통화를 바로 끊게 설정할 수 있어요. [통화 설정 가이드 보기](/docs/build/conversation/call-settings) ## 메뉴얼 출시 업무 절차 하나를 담는 지시 모듈인 메뉴얼을 출시했어요. 에이전트에 연결하면 대화 중 트리거 조건이 맞을 때만 본문을 불러와서, 프롬프트를 키우지 않고 절차를 다시 쓸 수 있어요. ### 주요 기능 * **[메뉴얼](/docs/build/manuals/overview)**: 메뉴얼을 만들어 에이전트에 연결하면 트리거가 맞는 순간 본문을 불러와요. * **[도구와 메뉴얼 참조](/docs/build/manuals/writing#도구와-다른-메뉴얼-참조하기)**: 본문에서 `/` 명령으로 도구와 다른 메뉴얼을 참조하고, 템플릿이나 문서 업로드로 초안을 만들 수 있어요. * **[API 지원](/api-reference/v3/introduction)**: `/manuals` 리소스로 메뉴얼을 만들고, 수정하고, 삭제할 수 있어요. `manualIds`로 에이전트 연결도 자동화할 수 있어요. [메뉴얼 가이드 보기](/docs/build/manuals/overview) ## 실행 대기음 추가 도구 실행이나 변수 추출이 끝날 때까지의 무음 구간을 소리로 채울 수 있게 됐어요. 응답이 느린 외부 API를 부를 때도 고객이 전화가 끊겼다고 느끼지 않아요. ### 주요 기능 * **[실행 대기음](/docs/build/tools/tool-call-sound)**: 타이핑과 대기 음악 4종 가운데 골라요. 에이전트가 말할 때는 소리가 꺼지고, 고객이 말하면 바로 멈춰요. * **설정 위치**: API 도구, 플로우의 API·도구·추출·문자 발신 노드, 메뉴얼에서 각각 설정할 수 있어요. [실행 대기음 가이드 보기](/docs/build/tools/tool-call-sound) ## 새 LLM 모델 추가 OpenAI의 `GPT-5.6 Luna`, `GPT-5.6 Terra`와 Google의 오픈 모델 `Gemma 4 31B`를 추가했어요. 에이전트 설정에서 골라 쓸 수 있어요. ### 주요 기능 * **GPT-5.6 Luna·GPT-5.6 Terra**: OpenAI의 새 gpt-5.6 계열 모델이에요. 추론 능력이 좋아져 복잡한 안내나 판단이 필요한 시나리오에 쓸 수 있어요. * **Gemma 4 31B**: 응답이 빨라 실시간 음성 대화에 알맞아요. # 2026년 9월 Source: https://docs.tryvox.co/changelog/2026/09 ## 문자 에이전트 출시 번호에 문자 에이전트를 연결하면 그 번호로 들어온 문자에 에이전트가 답하게 됐어요. 에이전트가 고객에게 먼저 문자를 보내 대화를 시작할 수도 있어요. 고객이 보낸 문자에 문자 에이전트가 답장하는 흐름 ### 주요 기능 * **[문자 에이전트 연결](/docs/operate/deploy/phone-numbers#문자-에이전트-연결하기)**: **배포 > 전화번호**에서 번호를 열고 **문자 설정**의 **인바운드 문자 에이전트**에서 답할 에이전트를 고르세요. * **[에이전트 문자 발신](/docs/operate/outbound/sms)**: **발신 > 문자**의 **에이전트** 탭에서 발신하면 에이전트가 첫 문자를 보내고, 고객이 답하면 같은 에이전트가 이어서 대화해요. [에이전트가 문자 대화 시작하기 가이드 보기](/docs/operate/outbound/sms) ## 광고 문자 무료 수신거부 출시 광고 문자를 보내는 번호에서 **광고 문자입니다**를 켜면 (광고) 표시와 무료 수신거부 안내가 문자에 자동으로 붙게 됐어요. 수신거부는 vox.ai가 제공하는 080 번호로 받아서 따로 080 번호를 준비하지 않아도 돼요. ### 주요 기능 * **[광고 문자 설정](/docs/operate/deploy/phone/sms-ad)**: **배포 > 전화번호**에서 번호를 열고 **부가서비스**의 **광고 문자입니다**를 켜세요. * **[광고 수신거부 관리](/docs/operate/deploy/blocked-numbers#광고-수신거부-관리하기)**: 고객이 080 번호로 수신거부하면 그 번호는 **차단 번호**에 **광고 수신거부**로 올라가고, 이 워크스페이스의 광고 문자만 막혀요. [광고 문자 가이드 보기](/docs/operate/deploy/phone/sms-ad) ## GPT-6 Sol·Luna 모델 추가 OpenAI의 `GPT-6 Sol`과 `GPT-6 Luna`를 추가했어요. 에이전트 설정의 모델 선택 목록에서 **추천**에 있어요. ## 웹페이지 지식 자동 동기화 출시 웹페이지로 등록한 지식을 원본 웹페이지의 최신 내용으로 다시 반영할 수 있게 됐어요. ### 주요 기능 * **[자동 동기화](/docs/build/knowledge/webpage#바뀐-내용-반영하기)**: **24시간마다 자동 동기화**를 켜면 등록한 주소를 하루에 한 번 다시 읽어요. * **[지금 동기화](/docs/build/knowledge/webpage#바뀐-내용-반영하기)**: 웹페이지 문서를 열고 **동기화**를 누르면 바로 반영해요. [웹페이지 가이드 보기](/docs/build/knowledge/webpage) ## 문자 부가서비스 신청 출시 전화번호 상세에서 문자 발신과 문자 수신을 직접 신청할 수 있게 됐어요. 운영자가 승인하면 그 번호로 문자를 보내고 받을 수 있어요. 번호에서 문자 발신과 문자 수신을 신청하고 승인을 거쳐 사용하는 순서 ### 주요 기능 * **[문자 발신·수신 신청](/docs/operate/deploy/phone/sms)**: **배포 > 전화번호**에서 번호를 열고 **부가서비스**의 **문자 발신**이나 **문자 수신**에서 **신청**을 누르세요. [문자 부가서비스 가이드 보기](/docs/operate/deploy/phone/sms) ## 웹사이트 위젯 대화 메뉴 추가 웹사이트 위젯 방문자가 대화를 새로 시작하거나 끝내고, 이전 대화를 다시 볼 수 있게 됐어요. ### 주요 기능 * **[대화 메뉴](/docs/operate/deploy/widget/modes#채팅으로-응대하기)**: 방문자가 위젯 메뉴에서 **새로 시작**, **이전 대화**, **대화 종료**를 골라요. * **[응답 안내](/docs/operate/deploy/widget/appearance)**: **표시** 탭의 **메시지**에서 **응답 안내**를 쓰면 위젯 헤더 아래에 보여요. [모양과 메시지 가이드 보기](/docs/operate/deploy/widget/appearance) ## 진행 중 통화 전환 API 출시 진행 중인 통화를 API 요청 한 번으로 상담사 전화번호나 SIP 주소로 넘길 수 있게 됐어요. CRM이나 PBX 같은 외부 시스템이 상담사 연결 시점을 정해요. 외부 시스템의 API 요청 한 번으로 진행 중인 통화를 에이전트에서 상담사에게 넘기는 흐름 ```bash cURL theme={null} curl --request POST \ --url https://client-api.tryvox.co/v3/calls/{call_id}/transfer \ --header "Authorization: Bearer $VOX_API_KEY" \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: transfer-request-001' \ --data '{ "mode": "warm", "destination": { "type": "phone", "target": "0261234567" }, "timeout_seconds": 30 }' ``` ### 주요 기능 * **[외부 시스템에서 전환 요청](/docs/build/tools/builtin/transfer-call#api로-진행-중-통화-넘기기)**: `POST /calls/{call_id}/transfer`를 호출하면 에이전트 도구 설정 없이 통화를 넘길 수 있어요. * **[즉시 전환과 안내 후 전환 선택](/docs/build/tools/builtin/transfer-call#전환-방식-고르기)**: 통화를 바로 넘기거나 대화 요약을 먼저 전한 뒤 연결해요. * **[API 참조](/api-reference/v3/introduction)**: **통화** 그룹에서 요청 필드와 오류 코드를 확인할 수 있어요. [통화 전환 가이드 보기](/docs/build/tools/builtin/transfer-call) ## 통화 기록 실시간 모니터링·당겨받기 출시 진행 중인 통화의 음성 파형과 대화를 실시간으로 볼 수 있게 됐어요. 상담사가 직접 받아야 할 통화는 전화번호를 지정해 바로 당겨받을 수 있어요. ### 주요 기능 * **[진행 중 통화 실시간 보기](/docs/operate/monitor/history#진행-중인-통화-지켜보기)**: **모니터링 > 기록**에서 진행 중인 통화를 열면 에이전트와 고객의 파형과 대화가 실시간으로 보여요. * **[당겨받기](/docs/operate/monitor/history#통화-당겨받기)**: 상담사 전화번호와 전환 방식을 고르면 통화가 상담사에게 넘어가요. [통화 기록 가이드 보기](/docs/operate/monitor/history) # CLI Source: https://docs.tryvox.co/docs/ai/cli 터미널에서 에이전트를 만들고, 검증하고, 배포할 수 있어요. vox CLI는 에이전트를 코드처럼 다루는 개발 도구예요. 에이전트 정의를 JSON 파일로 Git 저장소에 두고, 검증부터 배포까지 터미널에서 해요. 고친 파일은 git으로 리뷰하고 언제든 재현하거나 되돌릴 수 있어요. Claude Code, Codex 같은 코딩 에이전트와 함께 쓰도록 만들었어요. 모든 명령이 `--json` 출력을 지원해서 AI가 사람 도움 없이 에이전트를 만들고 고칠 수 있어요. ## 설치하기 npm이나 Homebrew로 설치하세요. ```bash npm theme={null} npm install -g @vox-ai/cli ``` ```bash Homebrew theme={null} brew install vox-public/tap/vox ``` ## 첫 에이전트 배포하기 로그인하고 첫 에이전트 프로젝트를 만드세요. ```bash theme={null} vox auth login # 브라우저에서 vox.ai 계정으로 로그인 vox auth whoami # 로그인 확인 vox init --agent main --type flow # 첫 에이전트 프로젝트 만들기 ``` `vox init`은 `agents/main/agent.json` 소스 파일을 만들어요. 이 파일을 고친 뒤 아래 순서로 배포하세요. ```bash theme={null} vox doctor # 로컬 파일의 흔한 실수 잡기 vox agent validate # 서버 검증 vox agent diff # 원격과의 차이 확인 vox agent push # 저장 vox agent version save # 버전 만들기 vox agent promote v1 --yes # 저장한 버전을 프로덕션에 반영 ``` 프로덕션 반영은 `version save`와 `promote`로 나뉘어 있어서, 실수로 운영 중인 에이전트를 바꾸지 않아요. `promote`에는 `version save`가 알려 준 버전(`v1`, `v2` 같은 값)과 `--yes`를 붙이세요. ## CLI로 할 수 있는 일 ### 에이전트 에이전트를 만들고, 가져오고, 고치고, 배포해요. 대시보드에서 만든 에이전트도 `pull`로 가져와 파일로 관리할 수 있어요. ```bash theme={null} vox agent add support_router --scaffold flow-router vox agent import dashboard-export.json --agent support_router vox agent set --agent main --data prompt.firstLine="안녕하세요. 무엇을 도와드릴까요?" vox agent pull --agent main vox agent push --agent main vox agent versions --agent main vox agent promote v3 --agent main --yes ``` ### 플로우 편집 [플로우 에이전트](/docs/build/flow/overview)의 노드와 연결을 명령으로 고쳐요. `graph`는 전체 플로우를 다이어그램으로 보여 줘요. ```bash theme={null} vox agent flow add-node check_account --type api --url https://api.example.com/check vox agent flow connect --from conversation --to check_account --condition "API 조회가 필요할 때" vox agent flow set --node check_account --data api_configuration.timeout_seconds=20 vox agent flow graph --format outline ``` ### 도구 에이전트가 통화 중에 부르는 [커스텀 도구](/docs/build/tools/api)를 파일로 관리해요. API 키 같은 비밀 값은 파일에 남지 않도록 참조 형태로만 적어요. ```bash theme={null} vox tool init crm_lookup --url https://api.example.com/customers/lookup \ --param "phone_number:string:고객 전화번호" vox tool validate crm_lookup vox tool push crm_lookup vox agent attach tool main crm_lookup --node lookup_customer ``` ### 지식 베이스 [지식 베이스](/docs/build/knowledge/overview)를 문서 단위로 정의하고 배포해요. 텍스트, 웹페이지, 저장소 안의 파일을 문서로 추가할 수 있어요. ```bash theme={null} vox knowledge init product_faq --name "Product FAQ" vox knowledge add-document product_faq docs --type webpage --url https://docs.tryvox.co vox knowledge push product_faq vox agent attach knowledge main product_faq --node conversation ``` ### 통화 터미널에서 바로 아웃바운드 통화를 걸고 결과를 확인해요. JSON 배열을 넘기면 여러 건을 차례로 발신해요. ```bash theme={null} vox call create --from <발신번호> --to <수신번호> --agent vox call list --status ended --agent vox call get --transcript ``` ### 대량 발신 [대량 발신](/docs/operate/outbound/campaigns)(`campaign`)을 만들고 진행을 제어해요. 대상은 `--to`를 반복하거나 `call_to` 객체 배열 파일을 `--tasks`로 넘기세요. ```bash theme={null} vox campaign create --name "9월 안내" --from <발신번호> --agent --tasks ./tasks.json vox campaign list --status ongoing vox campaign get vox campaign pause vox campaign resume vox campaign cancel --yes ``` ### 전화번호 보유 번호에 에이전트를 연결하고, [통신서비스 이용증명원](/docs/operate/deploy/phone/telecom-cert)을 발급하고, [발신표기번호](/docs/operate/deploy/phone/caller-id)를 등록해요. ```bash theme={null} vox number list vox number set-agent --inbound-agent vox number caller-id register --number 0212345678 --document ./certificate.pdf vox number certificate request ``` ### 위젯 웹사이트 [위젯](/docs/operate/deploy/widget/overview)을 만들고 게시해요. `list`, `get`, `create`, `update`, `delete`, `publish`, `unpublish` 명령 7개가 있고, `get --snippet`은 설치 코드를 출력해요. ```bash theme={null} vox widget create --agent-id --mode chat --branding '{"title":"상담"}' vox widget publish vox widget get --snippet vox widget list ``` ### 보이스와 모델 쓸 수 있는 LLM과 [보이스](/docs/build/voice/voice-select)를 조회하고, 보이스를 복제해요. ```bash theme={null} vox llm list vox voice list vox voice clone --file ./sample.wav --name "상담사 A" --language ko ``` ### 채팅 테스트 전화를 걸지 않고 터미널에서 에이전트와 대화해 봐요. `--input`을 반복하면 여러 턴 대화 시나리오를 한 번에 검증하고, `--voice`는 마이크로 실제 음성 대화를 해요. ```bash theme={null} vox chat --agent main --input "안녕하세요" vox chat --agent main \ --input "예약을 변경하고 싶어요" \ --input "예약번호는 A-100입니다" \ --json vox chat --agent main --voice ``` ### 워크스페이스 동기화 원격 워크스페이스 전체를 저장소로 가져오거나, 로컬과 원격이 얼마나 어긋났는지 확인해요. 워크스페이스가 여럿이면 저장소 하나에서 오가며 관리할 수 있어요. ```bash theme={null} vox sync status vox sync bootstrap --all --dry-run vox org list --tree vox org switch agency/brand-a ``` ### 워크스페이스 관리 [워크스페이스](/docs/workspace/overview) 정보와 통화 사용량·한도, 멤버, 청구서, [인증 상태](/docs/workspace/verification)를 조회하고 [하위 워크스페이스](/docs/workspace/sub-organizations)를 만들거나 삭제해요. 하위 워크스페이스는 `--sub-org`로 지정하세요. ```bash theme={null} vox org get vox org usage --sub-breakdown vox org members --all vox org invoice list --since 2026-01-01 vox org invoice get vox org verification status vox org create --name "브랜드 A" vox org delete --sub-org --yes ``` ## 코딩 에이전트와 함께 쓰기 vox CLI는 AI에게 맡겨 쓰는 것이 기본이에요. `vox init`을 실행하면 Claude Code와 Codex가 자동으로 읽는 스킬 파일이 프로젝트에 만들어져요. 그다음 코딩 에이전트에게 말로 요청하면 AI가 CLI를 불러 에이전트를 만들고, 검증하고, 배포해요. 클라이언트별 연결 방법은 [Claude Code·Codex에서 CLI 설치](/docs/ai/clients)에 있어요. ```text theme={null} 치과 예약 확인 에이전트 만들어줘. 환자 이름과 예약 시간을 확인하고, 변경이 필요하면 담당자에게 연결해줘. 만들고 나서 vox chat으로 예약 변경 시나리오까지 테스트해줘. ``` AI가 참고할 설계 가이드도 CLI 안에 들어 있어요. ```bash theme={null} vox guide coding-agent --brief --json # 코딩 에이전트용 운영 계약 vox agent plan --task "택배 배송 조회 인바운드 플로우" --json vox agent create --task "택배 배송 조회 인바운드 플로우" --json vox docs search "글로벌 노드" --json ``` `agent create --task`는 요청 의도를 분류해 인사, 조회, 성공·실패 안내, 상담사 연결까지 갖춘 초안을 한 번에 만들어요. ## JSON으로 결과 받기 모든 명령이 `--json`을 지원해요. 스크립트나 CI에서 결과를 파싱해 쓰세요. ```bash theme={null} vox agent list --json | jq '.data[].name' vox call get --json | jq '.data.transcript' vox agent diff --check # 변경이 있으면 exit 1 ``` ## 인증과 프로필 관리하기 로그인은 OAuth만 지원하고, 토큰은 OS 키체인에 저장돼요. API 키를 파일에 남기지 않아요. ```bash theme={null} vox auth login # 프로필 추가 vox auth switch # 계정·워크스페이스 전환 vox auth whoami # 현재 로그인 확인 vox auth logout # 로그아웃 ``` CI처럼 브라우저를 열 수 없는 환경에서는 환경 변수로 토큰을 넣으세요. | 환경 변수 | 용도 | | - | - | | `VOX_OAUTH_ACCESS_TOKEN` | 저장된 로그인 대신 쓸 액세스 토큰 | | `VOX_ORGANIZATION_ID` | 명령을 적용할 워크스페이스 | | `VOX_NO_UPDATE_NOTIFIER=1` | 새 버전 알림 끄기 | 공식 배포 빌드는 CLI 사용 정보와 로그인 계정 정보를 늘 수집해요. PostHog로 보내는 항목은 사용자 ID, 이메일, 이름, 프로필, install ID, 마지막 로그인 시각, 현재·기본 워크스페이스 정보, 명령 실행 정보예요. 프롬프트, 파일 경로와 내용, 명령 인자 값, 토큰, 시크릿, 메시지 내용, 고객 데이터는 수집하지 않아요. 공식 배포 빌드는 텔레메트리 수집을 끌 수 없어요. ## 문제가 생겼을 때 `vox upgrade`를 실행하세요. 지금 설치한 방식에 맞는 업그레이드 명령을 안내해요. `VOX_OAUTH_ACCESS_TOKEN`과 `VOX_ORGANIZATION_ID` 환경 변수를 설정하세요. 저장된 로그인 대신 이 토큰으로 명령을 실행해요. `vox sync status`로 로컬과 원격이 얼마나 어긋났는지 확인하세요. `vox agent diff`는 에이전트마다 원격과 다른 곳을 보여 줘요. ## 관련 문서 * [Claude Code·Codex에서 CLI 설치](/docs/ai/clients): 클라이언트별 스킬 파일과 CI 설정 * [AI 코딩 에이전트 개요](/docs/ai/overview): 코딩 에이전트에게 맡길 수 있는 일 * [에이전트 버전 관리](/docs/build/versioning): 버전 저장과 프로덕션 지정 # Claude Code·Codex에서 CLI 설치 Source: https://docs.tryvox.co/docs/ai/clients Claude Code, Codex 같은 코딩 에이전트에 vox CLI를 연결해 대화로 에이전트를 만들 수 있어요. 어떤 클라이언트를 쓰든 준비는 같아요. vox CLI를 설치하고 로그인한 뒤, 작업할 프로젝트에서 `vox init`을 실행하면 연결이 끝나요. ## CLI 연결하기 ```bash theme={null} npm install -g @vox-ai/cli # 또는 brew install vox-public/tap/vox vox auth login vox init --agent main --type flow ``` `vox init`은 에이전트 소스 파일과 함께 코딩 에이전트가 자동으로 읽는 스킬 파일을 프로젝트에 만들어요. 클라이언트마다 스킬 파일이 놓이는 자리만 달라요. `vox init`이 `.claude/skills/vox-ai/SKILL.md`를 만들어요. Claude Code는 프로젝트를 열 때 이 스킬을 자동으로 읽어서 따로 설치할 것이 없어요. `vox init`이 `.codex/skills/vox-ai/SKILL.md`를 만들어요. Codex도 프로젝트의 스킬을 자동으로 읽어서, 프로젝트에서 Codex를 열고 바로 요청하면 돼요. 스킬 파일은 설치된 `vox` 바이너리의 작업 가이드를 가리키는 일만 해요. 셸 명령을 실행할 수 있는 코딩 에이전트라면 아래 명령의 출력을 지침으로 넣어 같은 방식으로 쓸 수 있어요. 출력에는 에이전트 작성 규칙, 검증·배포 순서, 주의할 점이 담겨 있어요. ```bash theme={null} vox guide coding-agent --brief ``` 쓰는 코딩 에이전트의 지침 파일에 이 명령을 적어 두세요. ## 연결 확인 같은 프로젝트에서 코딩 에이전트를 열고 만들고 싶은 에이전트를 설명하세요. ```text theme={null} 치과 예약 확인 에이전트 만들어줘. 환자 이름과 예약 시간을 확인하고, 변경이 필요하면 담당자에게 연결해줘. 만들고 나서 vox chat으로 예약 변경 시나리오까지 테스트해줘. ``` 연결됐다면 코딩 에이전트가 CLI로 에이전트를 만들고, 검증하고, 테스트까지 진행해요. ## CI·헤드리스 환경에서 쓰기 브라우저 로그인 없이 환경 변수로 인증할 수 있어요. `VOX_OAUTH_ACCESS_TOKEN`과 `VOX_ORGANIZATION_ID`를 설정하면 CI 파이프라인에서도 같은 명령을 실행해요. 환경 변수 목록은 [CLI](/docs/ai/cli#인증과-프로필-관리하기)에 있어요. ## 문제가 생겼을 때 `vox agent skills refresh`를 실행하세요. 스킬 파일이 최신 템플릿으로 다시 만들어져요. 고치지 마세요. `.claude`와 `.codex` 아래의 `vox-ai` 스킬 파일은 CLI가 관리하는 산출물이라 다시 만들면 고친 내용이 사라져요. 프로젝트를 만들 때 `vox init --no-agent-skills`를 쓰세요. 이 옵션을 주면 스킬 파일을 만들지 않아요. ## 관련 문서 * [CLI](/docs/ai/cli): 전체 명령과 인증, JSON 출력 * [AI 코딩 에이전트 개요](/docs/ai/overview): 코딩 에이전트에게 맡길 수 있는 일 # AI 코딩 에이전트 개요 Source: https://docs.tryvox.co/docs/ai/overview vox CLI와 코딩 에이전트로 대화만으로 에이전트를 만들고, 배포하고, 개선할 수 있어요. AI로 vox.ai를 다루는 길은 [vox CLI](/docs/ai/cli)예요. CLI를 설치하고 프로젝트를 만들면 Claude Code, Codex 같은 코딩 에이전트가 에이전트 정의를 코드처럼 다뤄요. ## CLI 설치하고 시작하기 npm으로 설치하세요. Homebrew를 쓰면 `brew install vox-public/tap/vox`로 설치해요. ```bash theme={null} npm install -g @vox-ai/cli ``` 로그인한 뒤 작업할 폴더에서 `vox init`을 실행하세요. Claude Code와 Codex가 자동으로 읽는 스킬 파일이 프로젝트에 만들어져서 따로 설정할 것이 없어요. ```bash theme={null} vox auth login vox init --agent main --type flow ``` 같은 프로젝트에서 Claude Code나 Codex를 열고 만들고 싶은 에이전트를 설명하세요. 코딩 에이전트가 CLI로 에이전트를 만들고, 검증하고, 테스트까지 진행해요. ```text theme={null} 치과 예약 확인 에이전트 만들어줘. 환자 이름과 예약 시간을 확인하고, 변경이 필요하면 담당자에게 연결해줘. 만들고 나서 vox chat으로 예약 변경 시나리오까지 테스트해줘. ``` ## 코딩 에이전트에게 맡길 수 있는 일 CLI를 연결한 뒤에는 코딩 에이전트에게 아래 작업을 말로 요청할 수 있어요. 대시보드를 열지 않고도 만들기부터 개선까지 한 흐름으로 이어져요. * **만들기**: 프롬프트, 보이스, 지식 베이스, 도구를 설정해 에이전트를 만들고 고쳐요. * **테스트**: `vox chat`으로 전화 없이 여러 턴 대화 시나리오를 검증해요. * **배포**: 전화와 위젯 채널을 연결하고, 전화 발신과 대량 발신을 설정해요. * **모니터링**: 통화 기록과 녹음을 조회하고 실패 원인을 찾아요. * **개선**: 통화 결과를 보고 프롬프트와 플로우를 거듭 고쳐요. 에이전트 정의가 JSON 파일로 Git 저장소에 남아서 모든 변경을 git으로 리뷰하고 되돌릴 수 있어요. ## 관련 문서 * [CLI](/docs/ai/cli): 설치, 전체 명령, 코딩 에이전트와 함께 쓰는 흐름 * [Claude Code·Codex에서 CLI 설치](/docs/ai/clients): 클라이언트별 연결 방법과 CI 환경 설정 # 통화 설정 Source: https://docs.tryvox.co/docs/build/conversation/call-settings 통화 소리를 다듬고, 통화 길이를 관리하고, 키패드 입력과 통화 스크리닝에 대응할 수 있어요. 통화 설정은 에이전트가 전화에서 어떻게 들리고 언제 통화를 끝낼지 정해요. 에이전트 편집 화면에서 **통화 설정**을 펼쳐 바꾸세요. 에이전트 설정의 통화 설정 패널 ## 언제 사용하나요 * **무음이 어색할 때**: 배경 음악을 깔아 통화 분위기를 채워요. * **주변 소음이나 잡음에 에이전트가 반응할 때**: 노이즈 캔슬링과 인식 민감도로 걸러요. * **통화가 불필요하게 길어질 때**: 통화 시간이 곧 사용량이라, 세 가지 시간 설정으로 늘어지는 통화를 끊어요. * **발신 전화를 스마트폰의 AI 통화비서가 받을 때**: 통화 스크리닝으로 발신 목적을 남겨요. 수신자는 그 내용을 보고 전화를 받을지 정해요. ## 통화 소리 다듬기 * **배경 음악**: 카페, 사무실, 콜센터, 도서관 소리 중에서 고르세요. 볼륨은 옆 스피커 버튼에서 조절해요. * **노이즈 캔슬링**: 기본값은 **강한 노이즈 캔슬링 (타인 목소리 제거)** 항목이라 주변 사람 목소리까지 걸러요. 고객 목소리가 작아 말까지 걸러지면 **일반 노이즈 캔슬링**으로 낮추세요. * **인식 민감도**: 잡음에 반응하면 둔감함 쪽으로 옮기세요. 또렷한 말만 인식해요. 작은 목소리를 놓치면 민감함 쪽으로 옮기세요. ## 통화 길이 관리하기 * **다이얼 대기 시간**: 발신한 전화를 받지 않으면 이 시간 뒤에 끊어요. 기본 30초예요. * **최대 통화 시간**: 상담이 이 시간에 가까워지면 에이전트가 종료를 안내하고 마지막 인사로 마무리해요. 기본 15분이에요. * **무응답 대기 시간**: 상대가 이 시간 동안 말이 없으면 통화를 끝내요. 기본 30초예요. ## 키패드 입력 처리하기 * **DTMF 입력 시 발화 중단**: 켜면 고객이 첫 키를 누르는 순간 안내를 멈춰요. * **DTMF 종료 키 활성화**: 켜면 고객이 종료 키(예: #)를 누르는 즉시 입력을 처리해요. * **DTMF 타임아웃**: 마지막 키 입력 뒤 기다리는 시간이에요. 기본 3초예요. 키 입력이 통화에서 어떻게 모이고 처리되는지는 [DTMF](/docs/build/conversation/dtmf)를 보세요. DTMF 입력 시 발화 중단과 종료 키 스위치, 타임아웃 설정 ## 통화 스크리닝에 대응하기 **통화 스크리닝**을 켜고 응답 방식을 고르세요. **정적**은 적은 문구를 그대로 말하고, 최대 300자예요. **동적**은 적은 지시문으로 상황에 맞는 응답을 만들어 말해요. 두 방식 모두 [동적 변수](/docs/build/variables/dynamic-variables)를 쓸 수 있어요. 스크리닝 응대에 쓰는 통화 시간을 줄이려면 **응답 후 통화 종료**도 켜세요. 통화 스크리닝의 응답 방식과 문구 입력, 응답 후 통화 종료 스위치 ## 통화에서 일어나는 일 * **최대 통화 시간이 되면 인사로 마무리해요.** 종료 안내를 주고받는 동안 실제 종료는 설정값보다 조금 늦어질 수 있어요. * **통화 스크리닝은 발신 통화에만 적용돼요.** 꺼져 있으면 스크리닝을 만나도 원래 통화 흐름대로 진행해요. * **응답 후 통화 종료를 켜면 응답을 마치는 즉시 끊어요.** 수신자가 전화를 받으러 오는 중이어도 기다리지 않아요. 이렇게 끝난 통화는 통화 기록에 **에이전트 종료**로 남아요. 사유별 뜻은 [연결 종료 사유](/docs/operate/monitor/disconnection-reasons)를 보세요. DTMF 입력 시 발화 중단은 지금 안내만 멈추고, 종료 키는 키패드 입력 수집만 끝내요. 두 설정 모두 통화를 끝내지 않아요. ## 문제가 생겼을 때 인식 민감도를 둔감함 쪽으로 옮기세요. 둔감할수록 또렷한 말만 인식해요. 노이즈 캔슬링을 일반 노이즈 캔슬링으로 낮추세요. 기본값인 강한 노이즈 캔슬링은 주변 사람 목소리까지 걸러서, 작게 말하는 고객의 말도 걸러질 수 있어요. 응답 후 통화 종료를 끄세요. 켜 두면 응답을 마치는 즉시 끊어서, 한 번만 거는 통화에서는 수신자를 놓칠 수 있어요. 미연결 건을 다시 거는 대량 발신에서만 켜는 편이 안전해요. ## 관련 문서 * [DTMF](/docs/build/conversation/dtmf): 키패드 입력을 받고 안내를 멈추는 방식 * [첫 메시지](/docs/build/conversation/first-message): 대화 시작 방식 설정 * [발화 설정](/docs/build/conversation/speech-settings): 반응속도, 끼어들기, 키워드 등록 * [DTMF 전송 도구](/docs/build/tools/builtin/send-dtmf): 에이전트가 ARS 메뉴를 눌러야 할 때 * [연결 종료 사유](/docs/operate/monitor/disconnection-reasons): 종료 사유별 뜻과 대응 # DTMF Source: https://docs.tryvox.co/docs/build/conversation/dtmf 고객이 누른 키패드 입력으로 메뉴를 고르게 하거나, 에이전트가 다른 전화의 ARS 메뉴를 누르게 할 수 있어요. DTMF는 전화기 키패드를 누를 때 나는 톤 신호예요. 고객이 누른 키는 별도 설정 없이 에이전트가 알아들어요. 에이전트가 다른 전화의 ARS 메뉴를 눌러야 한다면 [DTMF 전송](/docs/build/tools/builtin/send-dtmf) 도구를 쓰세요. ## 언제 사용하나요 * **키패드 메뉴로 안내할 때**: "1번은 예약, 2번은 문의"처럼 고객이 키를 눌러 메뉴를 고르게 해요. * **여러 자리 번호를 입력받을 때**: 고객이 번호를 누르고 #으로 끝내면 에이전트가 입력 전체를 한 번에 받아요. * **대표번호로 전화해 내선이나 메뉴를 눌러야 할 때**: 에이전트가 ARS 안내를 듣고 [DTMF 전송](/docs/build/tools/builtin/send-dtmf) 도구로 키를 눌러요. ## 키패드 입력 받기 키마다 에이전트가 할 일을 프롬프트에 적으세요. 에이전트는 고객이 누른 키를 보고 그에 맞게 답해요. ```text theme={null} ## 키패드 안내 고객에게 다음과 같이 안내하세요: - 예약 확인은 1번 - 예약 변경은 2번 - 상담사 연결은 0번 고객이 키패드를 누르면 해당 번호에 맞는 안내를 진행합니다. ``` [통화 설정](/docs/build/conversation/call-settings#키패드-입력-처리하기)에서 **DTMF 타임아웃**으로 마지막 키 뒤 기다릴 시간을 정하세요. 고객이 입력을 끝낼 때를 직접 알리게 하려면 **DTMF 종료 키 활성화**를 켜고 프롬프트에 "번호를 입력한 뒤 #을 눌러 주세요"처럼 안내하세요. 긴 안내를 듣는 중에도 바로 메뉴를 고르게 하려면 같은 화면에서 **DTMF 입력 시 발화 중단**을 켜세요. ## 통화에서 일어나는 일 * **키 입력을 대화 맥락으로 받아요.** 에이전트에게는 `1234`처럼 전달돼요. 통화 기록, 스크립트, 웹훅에는 읽기 쉬운 `[DTMF] 1234` 꼴로 보일 수 있어요. * **마지막 키 뒤에 기다렸다가 한 번에 처리해요.** 기본 3초예요. 고객이 `1`, `2`, `3`, `4`를 이어서 누르면 `4` 뒤 3초가 지나 `1234`를 한 입력으로 처리해요. 기다리는 중에 입력이 이어지면 처음부터 다시 기다려요. * **종료 키를 켜면 기다리지 않아요.** 고객이 종료 키를 누르는 즉시 다음 응답으로 넘어가요. * **발화 중단을 켜면 첫 키에 안내가 멈춰요.** 이어지는 키는 계속 모았다가 타임아웃이나 종료 키 때 입력 전체에 답해요. 끄면 첫 키만으로는 안내를 멈추지 않고, 입력 묶음이 완성된 뒤 답해요. * **첫 메시지는 첫 메시지 설정을 따라요.** 끼어들 수 없도록 보호한 첫 메시지나 도구 안내는 키를 눌러도 멈추지 않아요. ## 문제가 생겼을 때 DTMF 종료 키 활성화를 켜고 종료 키를 누르도록 안내하세요. 종료 키가 없으면 마지막 키 뒤 DTMF 타임아웃만큼 기다렸다가 답해요. DTMF 입력 시 발화 중단을 켜세요. 첫 메시지 중이라면 첫 메시지 인터럽트 허용을 확인하세요. 첫 메시지는 그 설정을 따라요. DTMF 타임아웃을 늘리거나 종료 키를 켜세요. 키 사이 간격이 타임아웃보다 길면 그때까지 누른 키를 한 입력으로 처리해요. ## 관련 문서 * [통화 설정](/docs/build/conversation/call-settings): DTMF 발화 중단, 타임아웃, 종료 키 설정 * [DTMF 전송 도구](/docs/build/tools/builtin/send-dtmf): 에이전트가 ARS 메뉴를 누르는 도구 설정 * [첫 메시지](/docs/build/conversation/first-message): 첫 인사 중 끼어들기 설정 # 첫 메시지 Source: https://docs.tryvox.co/docs/build/conversation/first-message 고객의 용건부터 듣거나 준비한 인사로 통화를 시작할 수 있어요. 첫 메시지는 통화에서 누가 먼저 말할지 정해요. 이 페이지는 프롬프트 에이전트 기준이에요. 첫 메시지에서 정적 메시지를 고르고 인사 문구를 적은 화면 플로우의 시작 방식은 [플로우 개요](/docs/build/flow/overview)에서, 노드별 인사는 [대화 노드](/docs/build/flow/nodes/conversation-node)에서 정하세요. ## 언제 사용하나요 * **고객의 용건부터 들을 때**: **사용자가 먼저 말함**을 고르세요. 고객이 말을 시작할 때까지 기다려요. * **발신 목적을 먼저 알릴 때**: **AI가 먼저 말함 (동적 메시지)** 항목을 고르세요. 프롬프트에 발신 목적과 첫 인사 지침을 적어요. * **정해진 안내문으로 시작할 때**: **AI가 먼저 말함 (정적 메시지)** 항목을 고르세요. 적은 문구로 인사해요. 동적 인사의 프롬프트와 정적 문구에는 변수를 쓸 수 있어요. 예약일처럼 통화마다 바뀌는 값은 [동적 변수](/docs/build/variables/dynamic-variables)로 넘기세요. ## 첫 메시지 설정하기 **구축 > 에이전트**에서 프롬프트 에이전트를 여세요. 프롬프트 입력 영역 아래에 **첫 메시지**가 있어요. 위 상황에 맞춰 시작 방식을 고르세요. 기본값은 **AI가 먼저 말함 (동적 메시지)** 항목이에요. 정적 메시지를 고르면 문구 입력란이 나타나요. 고객에게 들려줄 인사를 적으세요. ```text theme={null} 안녕하세요. 예약 접수 안내입니다. 어떤 예약을 도와드릴까요? ``` 동적 메시지는 프롬프트에 인사 지침을 적어요. ```text theme={null} 첫 인사에서 예약 확인을 위해 전화했다고 안내하세요. 이어서 지금 통화할 수 있는지 물어보세요. ``` 첫 메시지 옆 톱니바퀴 버튼을 누르세요. 두 설정 모두 AI가 먼저 말할 때만 조정할 수 있어요. * **첫 발화 전 대기 시간**: 0\~5초, 기본값은 0초예요. 0.1초 단위로 조정해요. * **첫 메시지 인터럽트 허용**: 기본값은 켜짐이에요. 고객이 말할 때 인사를 멈추려면 켜 두고, 인사 도중 끼어들지 못하게 하려면 끄세요. 첫 발화 전 대기 시간과 첫 메시지 인터럽트 허용을 조정하는 설정 창 음성 테스트에서 첫 인사를 들어 보세요. 대기 중과 인사 중에 각각 말해 보세요. 변수를 썼다면 테스트에 쓸 값도 준비하세요. ## 통화에서 일어나는 일 AI가 먼저 말하도록 설정해도 인사를 건너뛸 수 있어요. 아래는 첫 발화 전 대기 시간을 2초로 둔 경우예요(예시). ```mermaid actions={false} theme={null} %%{init: {"gantt": {"leftPadding": 110, "barHeight": 24, "barGap": 6, "fontSize": 13, "sectionFontSize": 13, "topPadding": 40}}}%% gantt title 첫 발화 전 대기 2초, 인터럽트 허용 켜짐 (예시) dateFormat YYYY-MM-DD HH:mm:ss axisFormat %M:%S tickInterval 1second section 기다릴 때 대기 :a1, 2024-01-01 00:00:00, 2024-01-01 00:00:02 첫 인사 :active, a2, 2024-01-01 00:00:02, 2024-01-01 00:00:06 section 대기 중 말할 때 대기 :b1, 2024-01-01 00:00:00, 2024-01-01 00:00:01 고객 여보세요 :done, b2, 2024-01-01 00:00:01, 2024-01-01 00:00:02 첫 인사 없이 고객 말에 답함 :active, b3, 2024-01-01 00:00:03, 2024-01-01 00:00:06 section 인사 중 말할 때 대기 :c1, 2024-01-01 00:00:00, 2024-01-01 00:00:02 첫 인사 (중단) :active, c2, 2024-01-01 00:00:02, 2024-01-01 00:00:03 고객 말 :done, c3, 2024-01-01 00:00:03, 2024-01-01 00:00:05 고객 말에 답함 :active, c4, 2024-01-01 00:00:05, 2024-01-01 00:00:08 ``` * **보라색(대기)**: 통화 연결 뒤 첫 발화 전 대기 시간이에요. 이때 고객이 말하면 첫 인사를 건너뛰어요. * **파란색(에이전트)**: 첫 인사와 그 뒤 응답이에요. 인터럽트 허용이 켜져 있으면 인사 중 고객이 말할 때 인사를 멈춰요. * **회색(고객)**: 고객이 말하는 구간이에요. 동적 메시지는 프롬프트를 바탕으로 인사를 만들고, 정적 메시지는 적은 문구로 인사해요. 정적 문구가 비어 있으면 첫 인사를 하지 않아요. 인사가 시작된 뒤에는 **첫 메시지 인터럽트 허용**을 따라요. 이 설정은 정적 인사와 동적 인사에 모두 적용돼요. 꺼 두어도 대기 중 고객이 말하면 첫 인사를 건너뛰어요. 그 뒤 대화의 끼어들기는 [발화 설정](/docs/build/conversation/speech-settings)에서 조정하세요. ## 문제가 생겼을 때 시작 방식과 정적 문구 입력란을 확인하세요. 사용자가 먼저 말함은 고객의 말을 기다려요. 정적 문구가 비어 있거나 대기 중 고객이 말해도 인사를 건너뛰어요. 문구를 고정하려면 정적 메시지를 고르세요. 동적 메시지는 프롬프트를 보고 인사를 만들어요. 변수 값이 다르면 [동적 변수](/docs/build/variables/dynamic-variables)의 전달 방법을 확인하세요. 첫 메시지 인터럽트 허용을 끄고 다시 테스트하세요. 켜져 있으면 고객이 말할 때 첫 인사를 멈춰요. ## 관련 문서 * [동적 변수](/docs/build/variables/dynamic-variables): 통화마다 다른 값을 인사에 넣기 * [발화 설정](/docs/build/conversation/speech-settings): 첫 인사 뒤 대화의 끼어들기 조정 * [플로우 개요](/docs/build/flow/overview): 플로우의 시작 방식 설정 * [대화 노드](/docs/build/flow/nodes/conversation-node): 노드별 인사와 끼어들기 설정 * [에이전트 전환](/docs/build/tools/builtin/transfer-agent): 전환 뒤 다시 인사하는 문제 해결 * [통화 설정](/docs/build/conversation/call-settings): 무응답 종료와 키패드 입력 설정 # 발화 설정 Source: https://docs.tryvox.co/docs/build/conversation/speech-settings 고객 말을 충분히 듣고 답하도록 응답 타이밍과 끼어들기, 자주 틀리는 단어를 조정할 수 있어요. 고객이 말을 마치기 전에 답하거나, 상품명을 자주 틀리나요? 발화 설정에서 응답 타이밍과 끼어들기, 인식용 키워드를 조정하세요. 발화 설정 패널의 반응속도, 말 끼어들기 허용, 키워드 강조 ## 언제 사용하나요 * **고객이 긴 설명 중 잠깐 쉴 때**: 답을 너무 일찍 시작하면 반응속도를 낮추세요. * **안내 중 고객이 내용을 바로잡을 때**: 말 끼어들기를 허용해 고객 말을 듣게 하세요. * **상품명이나 서비스명을 자주 틀릴 때**: 키워드 강조에 그 단어를 등록하세요. ## 발화 설정 조정하기 에이전트 편집 화면 오른쪽에서 **발화 설정**을 여세요. **반응속도** 슬라이더는 0.0\~1.0이고 기본값은 1.0이에요. 고객 말을 더 기다리려면 값을 낮추세요. 답이 늦게 시작되면 값을 높여 비교하세요. 안내 중 정정을 받으려면 **말 끼어들기 허용**을 켜세요. 기본값은 켜짐이에요. 끄면 안내 중 겹친 말을 놓칠 수 있어요. **키워드 강조**에 단어를 쉼표로 나눠 적으세요. 기본값은 비어 있어요. 예: `정기배송, 안심보장`. 인식 모델이 단어를 알아듣도록 돕는 설정이라, 등록한 단어를 늘 정확하게 인식하지는 않아요. 편집기는 바꾼 내용을 자동으로 저장해요. 음성 테스트에서 설명 중 잠깐 쉬거나 안내 도중 말을 걸어 보세요. 등록한 단어도 같은 문장으로 말해 비교하세요. ## 통화에서 일어나는 일 반응속도가 높으면 고객이 잠깐 쉬는 틈에 바로 답하고, 낮으면 고객이 말을 마칠 때까지 조금 더 기다렸다가 답하는 모습 * **고객 말이 끝났는지 판단한 뒤 답해요.** 반응속도는 이 판단의 대기 시간에 관여해요. 실제 응답 시점은 음성 인식 방식에도 영향을 받고, 에이전트가 말하는 속도는 바뀌지 않아요. * **끼어들기를 감지하면 말을 멈춰요.** 허용을 켜도 모든 소리에 바로 멈추지는 않아요. * **끼어들기를 막으면 겹친 음성을 버릴 수 있어요.** 겹친 말을 보관했다가 처리하는 설정이 아니라서, 안내가 끝난 뒤 다시 말하도록 요청하세요. 첫 인사 중 끼어들기는 [첫 메시지](/docs/build/conversation/first-message)에서, 플로우의 끼어들기는 [대화 노드](/docs/build/flow/nodes/conversation-node)에서 따로 정하세요. ## 문제가 생겼을 때 반응속도를 낮춘 뒤 같은 문장으로 테스트하세요. 문장 중간에 쉬는 상황도 함께 확인하세요. 음성 인식 설정도 확인하세요. 반응속도는 발화 종료 판단에만 관여해서, 답을 만들거나 도구를 실행하는 시간까지 줄이지는 않아요. 말 끼어들기 허용이 켜져 있는지 확인하세요. 첫 메시지와 플로우 노드는 따로 설정해요. 반응속도를 높이는 것만으로는 끼어들기가 허용되지 않아요. 단어의 철자와 쉼표 구분, 인식 언어를 확인하세요. 키워드 반영 방식은 인식 모델마다 달라요. 일부 모델은 키워드 강조를 지원하지 않아요. ## 관련 문서 * [음성 인식 & 발화](/docs/build/voice/voice-select): 인식 언어, 인식 속도, 목소리 속도 설정 * [발음 가이드](/docs/build/voice/pronunciation-guide): 에이전트가 읽는 발음 바로잡기 * [통화 설정](/docs/build/conversation/call-settings): 잡음, 인식 민감도, 키패드 입력 시 발화 중단 # 고객 속성 Source: https://docs.tryvox.co/docs/build/customer-memory/attributes 멤버십 등급이나 관심 상품 같은 고객 값을 정한 형식으로 대화에서 자동으로 모을 수 있어요. 고객 속성은 `멤버십 등급: 골드`, `첫 상담일: 2026-07-12`처럼 워크스페이스가 정한 항목에 맞춰 저장하는 고객 값이에요. 대화가 끝나면 값이 자동으로 채워져서, 상담 뒤에 따로 입력하지 않아도 고객을 분류하거나 외부 시스템과 맞출 수 있어요. ## 언제 사용하나요 * **고객의 최근 관심사를 분류할 때**: 관심 상품을 문자열 속성으로 두고, 새 값으로 늘 덮어써 최신 상태를 유지해요. * **정해진 단계로 고객을 나눌 때**: 멤버십 등급을 열거형 속성으로 두고 대화마다 갱신해요. * **처음 확인한 값을 남길 때**: 최초 유입 경로나 첫 상담일을 비어 있을 때만 채워 처음 값을 지켜요. 긴 상담 맥락이나 예외 사항은 [메모리](/docs/build/customer-memory/memory)에 두세요. 주문 상태처럼 원본 시스템에서 최신 값을 확인해야 하는 정보는 자동 추출 대신 API로 맞추세요. ## 고객 속성 만들기 **설정 > 고객 속성**에서 **추가**를 누르고 타입을 고르세요. 타입은 만든 뒤 바꿀 수 없어요. | 타입 | 저장하는 값 | 예 | | - | - | - | | **문자열** | 짧은 글 | 관심 상품 | | **숫자** | 정수나 소수 | 예상 구매 수량 | | **불리언** | 예 또는 아니요 | 재연락 희망 여부 | | **열거형** | 미리 정한 선택지 중 하나 | 멤버십 등급(브론즈·실버·골드) | | **날짜** | `YYYY-MM-DD` 꼴의 날짜 | 첫 상담일 | **이름**에 속성 이름을 적으세요. 한 속성에는 한 가지 사실만 담으세요. `관심 상품 및 구매 시기`보다 `관심 상품`, `구매 예정일`로 나누면 검색하고 연동하기 쉬워요. **추출 지시문**에는 어떤 말을 근거로 값을 뽑을지 적으세요. 예: "고객이 구매 의사를 밝힌 제품명". 구체적으로 적을수록 정확하게 뽑아요. 열거형이면 **선택 옵션**에 서로 겹치지 않는 값을 적으세요. 이미 값이 있을 때 새로 뽑은 값을 어떻게 할지 **충돌 처리**에서 고르세요. **항상 덮어쓰기**는 새 값으로 바꿔요. **비어 있을 때만**은 저장된 값이 없을 때만 넣으니, 처음 확인한 값을 지켜야 할 때 고르세요. **저장**을 누르세요. 자동 추출은 에이전트의 **메모리 활성화**가 켜져 있어야 동작해요. 켜는 방법은 [메모리](/docs/build/customer-memory/memory)를 보세요. 고객 속성 추가 창의 이름, 추출 지시문, 충돌 처리 ## 통화에서 일어나는 일 * **대화가 끝난 뒤 값을 뽑아요.** 메모리를 켠 에이전트의 대화가 끝나면 대화에 근거가 있는 값만 뽑아요. 고객이 말하지 않은 내용을 짐작해 채우지 않아요. * **속성은 만든 뒤의 대화부터 채워요.** 기존 고객에게 거슬러 적용하지 않아요. * **다음 대화에 함께 전달돼요.** 같은 고객이 다시 연락하면 저장된 속성 값이 메모리와 함께 에이전트에게 전달돼요. 골드 등급 고객에게 전용 혜택을 먼저 안내하는 것처럼 값을 어떻게 쓸지는 프롬프트에 적으세요. ## 저장된 값 관리하기 **모니터링 > 고객**에서 고객 상세를 열면 속성 값을 확인하고 바로 고칠 수 있어요. 값을 비우면 저장된 값이 지워져요. 화면이나 API로 직접 바꾼 값에는 충돌 처리가 적용되지 않아요. 쓰지 않는 속성은 **설정 > 고객 속성** 목록에서 비활성화하세요. 자동 추출에서 빠져요. 속성 정의는 [v3 API](/api-reference/v3/introduction)로도 만들고, 조회하고, 고치고, 지울 수 있어요. ## 문제가 생겼을 때 에이전트의 메모리 활성화와 속성의 활성 상태를 확인하세요. 속성은 만든 뒤의 대화부터 채우고, 대화에 근거가 없으면 비워 둬요. 고객 상세 화면이나 API에서 직접 고치세요. 충돌 처리를 비어 있을 때만으로 두면 자동 추출로는 기존 값을 바꾸지 않아요. 분류할 값은 열거형 속성으로 새로 만들고 기존 값을 옮기세요. 문자열은 표기가 제각각이라 검색과 집계가 어렵고, 타입은 만든 뒤 바꿀 수 없어요. 운영 중인 속성은 기존 값을 옮길 방법을 먼저 정한 뒤 이름을 바꾸세요. 이름을 바꿔도 고객에게 저장된 기존 값은 새 이름으로 옮겨지지 않아요. ## 관련 문서 * [메모리](/docs/build/customer-memory/memory): 대화에서 확인한 사실을 문장으로 기억하기 * [고객 메모리 개요](/docs/build/customer-memory/overview): 고객 속성과 메모리 중 저장할 곳 고르기 * [고객](/docs/operate/monitor/customers): 고객 상세에서 속성 값 보고 고치기 # 메모리 Source: https://docs.tryvox.co/docs/build/customer-memory/memory 지난 대화에서 확인한 사실을 기억해 두고, 같은 고객이 다시 연락하면 에이전트가 이어서 응대하게 할 수 있어요. 메모리를 켜면 에이전트가 대화에서 확인한 사실을 고객별로 남겨 둬요. 같은 고객이 다시 연락하면 그 내용을 알고 응대를 시작해서, 고객에게 같은 내용을 다시 묻지 않아요. ## 언제 사용하나요 * **이전 문의를 이어서 처리할 때**: "배송 지연으로 문의했고 금요일까지 확인하기로 함" 같은 약속을 기억해요. * **고객의 반복되는 선호를 반영할 때**: "택배보다 매장 픽업을 선호함"처럼 매번 다시 묻지 않아요. * **다음 상담에서 맥락을 알아야 할 때**: "설치 일정은 배우자와 상의한 뒤 다시 연락하기로 함"을 남겨요. 멤버십 등급처럼 분류할 값은 [고객 속성](/docs/build/customer-memory/attributes)에 두세요. 주문 상태처럼 실시간으로 확인해야 하는 값은 [API 도구](/docs/build/tools/api)로 조회하세요. ## 메모리 켜기 에이전트 편집 화면의 **메모리**에서 **메모리 활성화**를 켜세요. 메모리와 [고객 속성](/docs/build/customer-memory/attributes) 자동 추출이 함께 시작되고, 프롬프트는 고치지 않아도 돼요. 메모리 설정 설명과 메모리 활성화 스위치 ## 통화에서 일어나는 일 * **대화가 끝나면 기억할 사실을 추려요.** 응대 중이 아니라 끝난 뒤에 하므로 대화 품질에 영향이 없어요. 정리해 저장하기까지 수십 초에서 수 분 걸릴 수 있어요. * **사실을 두 유형으로 나눠 저장해요.** **지속 정보**는 시간이 지나도 그대로인 사실(택배보다 매장 픽업을 선호함)이고, **최근 상황**은 진행 중인 이슈나 최근 상태(금요일까지 배송 확인을 요청함)예요. 유형은 vox.ai가 내용을 보고 정해요. * **다음 대화를 시작할 때 전달해요.** 첫 응답을 만들기 전에 전달해서 첫마디부터 맥락이 반영돼요. 같은 고객의 고객 속성 값도 함께 전달해요. * **채널이 달라도 이어져요.** 전화, 문자, 웹과 앱의 채팅·음성 세션에서 모두 동작해요. 같은 에이전트라면 전화에서 쌓인 내용을 다음 채팅에서 이어서 써요. * **에이전트를 넘겨도 메모리를 다시 불러오지 않아요.** 통화를 다른 에이전트에게 넘기면 처음 전달받은 내용을 그대로 유지한 채 대화를 이어가요. * **본인 확인을 대신하지 않아요.** 메모리에 이름이나 지난 주문이 남아 있어도 계정 소유를 증명하지 않아요. 워크플로에 본인 확인 단계가 있으면 그대로 진행해요. * **메모리 속 문장을 명령으로 따르지 않아요.** 지시처럼 보이는 문장이 섞여도 에이전트는 참고 사실로만 다뤄요. 개인정보 마스킹을 켠 에이전트도 메모리를 쓸 수 있어요. vox.ai는 마스킹된 대화에서 메모리와 고객 속성을 뽑아요. ## 메모리 직접 관리하기 **모니터링 > 고객**에서 고객 상세를 열면 메모리를 확인하고 직접 추가, 수정, 삭제할 수 있어요. 추가할 때는 참고할 에이전트와 유형을 함께 고르고, 한 건에 512자까지 적을 수 있어요. [v3 API](/api-reference/v3/introduction)로도 메모리를 조회, 추가, 삭제하거나 조건에 맞춰 한 번에 정리할 수 있어요. 다음 대화에 필요한 사실만 남기고, 고객이 직접 말했거나 상담에서 확인한 내용만 적으세요. 메모리는 계속 쌓이니 오래되거나 잘못된 항목은 검토해서 지우세요. 메모리를 수정하면 직접 입력한 메모리로 다시 저장돼요. 원래 어느 통화나 채팅에서 나온 내용인지 가리키던 출처 연결은 사라지고, 기억된 시점도 수정한 시점으로 바뀌어요. ## 문제가 생겼을 때 에이전트의 메모리 활성화와 고객 식별을 확인하세요. 고객이 식별돼야 메모리를 저장하고 불러와요. 고객이 말하지 않은 대화는 분석하지 않고, 대화가 끝난 뒤 저장까지 수십 초에서 수 분 걸릴 수 있어요. 고객 상세에서 그 메모리를 수정하거나 삭제하세요. 재고, 배송 상태, 잔액처럼 자주 바뀌는 값은 메모리 대신 원본 시스템을 조회하게 하세요. 그 값을 고객 속성으로 정의하세요. 메모리는 자유 문장이라 검색, 분류, 외부 연동에는 정한 형식의 고객 속성이 맞아요. ## 관련 문서 * [고객 메모리 개요](/docs/build/customer-memory/overview): 고객 속성과 메모리 중 저장할 곳 고르기 * [고객 속성](/docs/build/customer-memory/attributes): 정한 형식으로 고객 값 모으기 * [고객](/docs/operate/monitor/customers): 고객 상세에서 메모리 보고 고치기 * [API 도구](/docs/build/tools/api): 실시간으로 바뀌는 값을 원본 시스템에서 조회하기 # 고객 메모리 개요 Source: https://docs.tryvox.co/docs/build/customer-memory/overview 에이전트가 지난 대화에서 확인한 고객 정보를 기억했다가 다음 대화에 쓰게 할 수 있어요. 에이전트는 기본적으로 모든 대화를 처음부터 시작해요. 메모리를 켜면 지난 대화에서 확인한 정보를 고객별로 기억했다가 같은 고객의 다음 응대에 써요. 고객 목록의 고객, 최근 접촉, 에이전트와 대화 수 ## 언제 사용하나요 * **같은 고객이 자주 다시 연락할 때**: 지난 문의와 선호를 참고해 같은 설명을 다시 묻지 않아요. * **예약이나 접수를 받을 때**: 선호 지점은 고객 속성으로 관리하고, 이전 요청의 맥락은 메모리로 남겨요. * **CRM과 고객 정보를 맞출 때**: 외부 고객 ID로 대화를 고객에게 묶고, 정해진 형식의 속성을 외부 시스템과 동기화해요. ## 고객 메모리로 할 수 있는 일 * **다시 묻지 않아요.** 고객이 다시 연락하면 에이전트가 지난 대화에서 확인한 사실을 알고 응대를 시작해요. "지난번에 문의하신 건은 어떻게 되셨나요?"처럼 이어서 말할 수 있어요. * **고객 정보가 저절로 쌓여요.** 통화나 채팅이 끝나면 대화에서 핵심 정보를 추려 고객별로 저장해요. 상담 뒤에 따로 입력하지 않아도 돼요. * **정한 형식으로 정리돼요.** 멤버십 등급, 관심 상품처럼 워크스페이스가 정한 항목에 맞춰 값을 채워요. ## 저장할 곳 고르기 통화, 채팅, 메모리가 묶이는 고객 기록이에요. 전화번호나 외부 고객 ID로 고객을 알아보고 기록을 한 곳에 모을 때 보세요. 정한 형식으로 저장하는 고객 값이에요. 멤버십 등급처럼 분류하거나 외부 시스템에 넘길 값일 때 고르세요. 대화에서 확인한 사실을 문장으로 남겨요. 매장 픽업 선호처럼 다음 상담에서 참고할 맥락일 때 고르세요. 주문 상태나 계좌 잔액처럼 실시간으로 바뀌는 값은 메모리에 두지 마세요. 늘 최신 값을 확인해야 하는 정보는 [API 도구](/docs/build/tools/api)로 원본 시스템을 조회하는 편이 안전해요. ## 고객 메모리 시작하기 전화번호로 자동 식별할지, CRM의 외부 고객 ID나 브라우저 방문자 ID를 넘길지 정하세요. 자세한 방법은 [고객](/docs/operate/monitor/customers)을 보세요. 분류하거나 연동할 값이 있다면 [고객 속성](/docs/build/customer-memory/attributes)을 먼저 만드세요. 자유 형식의 대화 맥락만 필요하면 건너뛰어도 돼요. 에이전트 편집 화면의 **메모리**에서 **메모리 활성화**를 켜세요. 메모리와 고객 속성 자동 추출이 함께 시작돼요. 대화가 끝나면 **모니터링 > 고객**에서 고객 상세를 열어 메모리와 속성을 확인하세요. ## 통화에서 일어나는 일 * **대화가 끝나면 분석해요.** 메모리를 켠 에이전트와 식별된 고객의 통화나 채팅이 끝나면 대화를 분석하고, 고객 속성도 같은 분석에서 함께 갱신해요. * **고객이 말하지 않은 대화는 건너뛰어요.** 고객 발화가 없는 대화는 분석하지 않아요. * **다음 대화를 시작할 때 전달해요.** 같은 고객의 다음 통화나 채팅이 시작되면 저장된 메모리와 속성이 에이전트에게 전달돼요. 자세한 동작은 [메모리](/docs/build/customer-memory/memory)를 보세요. ## 관련 문서 * [메모리](/docs/build/customer-memory/memory): 대화에서 확인한 사실을 기억하고 관리하기 * [고객 속성](/docs/build/customer-memory/attributes): 정한 형식으로 고객 값 모으기 * [고객](/docs/operate/monitor/customers): 고객을 알아보고 기록 모아 보기 # 글로벌 노드 Source: https://docs.tryvox.co/docs/build/flow/advanced/global-node 대화가 어느 단계에 있든 거절이나 상담사 연결 요청 같은 공통 상황을 한 노드에서 처리할 수 있어요. 글로벌 노드는 전환 조건만 맞으면 플로우의 여러 대화 노드에서 곧바로 넘어올 수 있는 노드예요. 모든 대화 노드에 같은 전환 조건을 하나씩 잇지 않아도 공통 상황을 한곳에서 처리해요. 대화 노드 설정 패널에서 글로벌 노드를 켜고 전환 조건에 사람 상담사와 대화를 원하는 경우를 적은 화면 ## 언제 사용하나요 * **고객이 통화를 거절할 때**: "지금은 시간이 없어요", "나중에 다시 전화할게요" 같은 말에 어느 단계에서든 같은 방식으로 답하고 마무리해요. * **사람 상담사를 찾을 때**: 대화 도중 상담사 연결을 원하면 전환 안내 노드로 넘겨요. * **어느 단계에서나 나오는 질문에 답할 때**: 운영 시간이나 위치 같은 자주 묻는 질문을 한 노드에서 답하고, 정해 둔 다음 단계로 이어가요. ## 글로벌 노드 설정하기 거절이나 상담사 연결처럼 공통으로 처리할 상황을 맡을 노드를 추가하세요. 글로벌 노드로 지정할 수 있는 노드는 대화 노드, 종료 노드, 문자 발신 노드예요. 노드를 선택하고 설정 패널에서 **글로벌 노드**를 켜세요. 아래에 **전환 조건** 칸이 나와요. **전환 조건**에 이 노드로 넘어올 상황을 적으세요. 조건은 구체적으로 적어야 해요. 모호하면 뜻하지 않은 때에 넘어와요. ```text theme={null} 고객이 사람 상담사와 통화를 원한다고 명확히 말한 경우 ``` 글로벌 노드가 대화 노드라면 처리를 마친 뒤 돌아갈 노드나 [종료 노드](/docs/build/flow/nodes/end-node)로 가는 전환 조건을 추가하고 연결하세요. ## 통화에서 일어나는 일 * **대화 노드에서 고객이 말하면 글로벌 조건도 함께 판단해요.** 지금 노드의 전환 조건과 글로벌 노드의 전환 조건 가운데 맞는 것으로 넘어가요. * **대화 노드 밖에서는 넘어가지 않아요.** 시작, 종료, 통화 전환, API, 도구, 조건, 추출, 문자 발신 노드는 글로벌 조건을 보지 않고 자기 경로대로 진행해요. * **여러 글로벌 조건이 함께 맞으면 가장 알맞은 하나를 골라요.** 조건이 겹치지 않게 구체적으로 적으세요. * **원래 노드로 저절로 돌아가지 않아요.** 글로벌 노드에 연결한 전환 조건을 따라 다음 노드로 넘어가요. 글로벌 노드의 개수에는 제한이 없어요. 다만 많을수록 조건이 겹치기 쉬우니 꼭 필요한 상황에만 두세요. ## 문제가 생겼을 때 전환 조건을 더 구체적으로 고치세요. 「고객이 불만을 말하는 경우」처럼 넓은 조건은 대화 중 여러 말에 맞아 버려요. 전환 조건을 고객이 실제로 하는 말에 맞게 고치고, 테스트 통화에서 그 말을 해 보세요. 글로벌 조건은 고객이 대화 노드에서 말할 때만 판단해서 다른 노드를 지나는 동안에는 넘어가지 않아요. 글로벌 노드에 전환 조건을 추가하고 돌아갈 노드나 종료 노드에 연결하세요. 연결이 없으면 글로벌 노드에 머물러요. ## 관련 문서 노드마다 다음으로 넘어갈 조건을 정할 수 있어요. 공통 상황에 답할 대화를 설정할 수 있어요. 거절한 고객에게 인사하고 통화를 끝낼 수 있어요. 노드를 추가하고 앞뒤 노드와 연결할 수 있어요. # API로 플로우 작성 및 검증 Source: https://docs.tryvox.co/docs/build/flow/api-authoring v3 API의 flow 필드로 플로우 에이전트 그래프를 작성하고 검증하고, 기존 flow_data에서 옮길 수 있어요. v3 API에서 플로우 에이전트를 만들거나 수정할 때는 `flow` 필드를 쓰세요. `flow`는 외부 통합을 위한 공개 그래프 계약이에요. `flow_data`는 기존 빌더 호환용 필드이고, 둘을 함께 보내면 `flow`가 우선해요. GPT-Live, Grok Voice, Gemini Live는 `single_prompt` 에이전트에서만 지원해요. `type: "flow"` 에이전트에 `gpt_live`, `grok_voice`, `gemini_live` 런타임을 보내면 거부되고, 기존 Flow 에이전트는 `pipeline` 런타임을 써요. `flow.nodes[].data.llm`은 기존 Flow의 노드별 LLM 설정으로 보존할 수 있지만 네이티브 실시간 런타임 기능은 아니에요. ## 필드 선택 | 필드 | 상태 | 사용 시점 | | - | - | - | | `flow` | 권장 | 새 플로우 만들기, 전체 그래프 교체, API·SDK·MCP 기반 작성 | | `flow_data` | 지원 종료 예정 | 기존 빌더 형태를 이미 저장하거나 읽는 통합의 호환 유지 | | 둘 다 생략 | 허용 | `type="flow"`로 만들면 서버가 기본 그래프를 만들어요 | | 둘 다 전송 | 허용 | `flow`만 처리하고 `flow_data`는 검증 전에 무시해요 | `flow`와 `flow_data`는 모두 그래프 전체를 바꿔요. 일부 필드만 보내 그래프를 부분 수정할 수는 없어요. `PATCH /v3/agents/{agent_id}`에서 `flow` 필드를 생략하면 지금 그래프를 유지해요. `flow: null`은 거부돼요. ## 그래프 수정과 revision 보호 `GET /v3/agents/{agent_id}?version=current` 응답의 `head_revision`과 `flow_revision`을 읽고, 같은 상태를 기준으로 그래프 전체를 `PATCH`하세요. 본문 최상위에 두 값을 `expected_head_revision`, `expected_flow_revision`으로 넘기세요. `REVISION_CONFLICT`가 돌아오면 최신 그래프를 자동으로 가져와 다시 저장하지 마세요. 사용자에게 충돌을 알리고, 사용자가 확인한 최신 그래프와 의도한 변경을 병합한 뒤 새 revision으로 다시 요청하세요. ## 그래프 구조 `flow`는 `nodes`와 `edges`로 이뤄져요. | 항목 | 필수 값 | 설명 | | - | - | - | | `nodes[].id` | 필수 | 그래프 안에서 유일한 노드 ID | | `nodes[].type` | 필수 | `begin`, `conversation`, `condition`, `api`, `endCall` 같은 노드 타입 | | `nodes[].position` | 필수 | 캔버스 좌표. 서버가 좌표를 만들지 않아요 | | `nodes[].data` | 선택 | 노드별 설정. 라우팅 키는 `edges`로 표현해요 | | `edges[].source` | 필수 | 출발 노드 ID | | `edges[].target` | 필수 | 도착 노드 ID | | `edges[].condition` | 필수 | `ai`, `logic`, `fallback` 가운데 하나 | | `edges[].skip_user_response` | 선택 | 사용자 응답을 기다리지 않고 다음 노드로 이동할지 | `nodes[].data`에 `transitions`, `logicalTransitions`, `logical_transitions`, `globalNodeSettings`, `global_node_settings`를 넣지 마세요. 기존 빌더 내부 키라서 `flow`에서는 `edges`와 `global_node_setting`으로 표현해요. ## 노드별 data 스키마 `flow.nodes`는 `BeginFlowNode`, `ConversationFlowNode` 같은 노드 타입별 스키마로 나뉘어요. `nodes[].data`도 노드 타입별 엄격한 스키마를 따르고, 문서에 없는 키를 보내면 `FLOW_V2_INVALID`로 거부돼요. 작성할 때는 `nodes[].type`에 맞는 v2 data 스키마를 참고하세요. 예를 들어 `begin`은 `BeginFlowNodeData`, `conversation`은 `ConversationFlowNodeData`, `api`는 `ApiFlowNodeData`, `transferCall`은 `TransferCallFlowNodeData`를 써요. [스키마 레지스트리](/api-reference/v3/introduction#스키마-레지스트리)에서도 같은 계약을 확인할 수 있어요. | 스키마 | 용도 | | - | - | | `/v3/schemas/flow-schema/flow-data` | 전체 `flow` 그래프 스키마 | | `/v3/schemas/flow-schema/node-{type}` | 그 노드의 v2 래퍼와 `data` 스키마 | | 위치 | 이름 규칙 | | - | - | | `flow.nodes`, `flow.edges`, `edge.condition` | v3 API 기본 규칙인 snake\_case를 써요 | | `edges[].skip_user_response` | 기존 `isSkipUserResponse` 전환을 `edges` 필드로 올린 값이에요 | | `nodes[].data.global_node_setting` | 기존 `globalNodeSettings`를 대체하는 v2 글로벌 노드 표시예요. `conversation`, `sendSms`, `endCall`에서만 허용해요 | | `nodes[].data`의 일반 노드 설정 | snake\_case 키를 써요. 예: `first_line_type`, `prompt_type`, `tool_id`, `api_configuration`, `transfer_configuration` | v2 `flow`는 라우팅과 글로벌 설정을 노드 밖으로 옮겼어요. 기존 빌더(`flow_data`)에서 `nodes[].data` 안에 두던 키는 v2에서 아래처럼 자리가 바뀌어요. | 기존 빌더(`flow_data`)의 `node.data` | v2 `flow`에서의 표현 | | - | - | | `transitions` | `edges`(분기 조건은 `edge.condition`) | | `logicalTransitions`, `logical_transitions` | condition 노드 분기는 `edge.condition`의 `logic` | | `globalNodeSettings`, `global_node_settings`(복수) | `nodes[].data.global_node_setting`(단수 표시) | `nodes[].data`에 위 빌더 내부 키를 넣으면 저장이 거부돼요. 각 노드 타입의 정확한 `data` 필드 목록은 `/v3/schemas/flow-schema/node-{type}`에서 확인하세요. 노드별로 알아 둘 점은 다음과 같아요. * **사전 멘트**: `prompt_type`, `prompt`, `static_sentence`(사전 멘트 모드 none, static, dynamic)는 `conversation`, `api`, `tool`, `sendSms`, `transferCall`, `endCall`에서 받아요. `transferCall`의 warm 위스퍼 멘트는 별도 필드(`warm_transfer_prompt`, `warm_transfer_static_sentence`)예요. * **`transferAgent`**: `agent`, `preserve_chat_context`만 받아요. `prompt`는 없어요. * **`conversation`의 지식 베이스**: `knowledge.rag_enabled`와 `knowledge.knowledge_ids`로 설정해요. 최상위 `knowledge_ids`는 받지 않아요. * **`extraction`의 추출 프롬프트**: `extraction_configuration.extraction_prompt`에 적어요. 최상위 `prompt`는 받지 않아요. * **`note`**: 에디터 주석 노드예요. `content`, `width`, `height`만 받고 `name`은 받지 않아요. note로 향하거나 note에서 나가는 전환은 저장이 거부돼요. ## 플로우 에이전트 만들기 예시 ```bash theme={null} curl https://client-api.tryvox.co/v3/agents \ -H "Authorization: Bearer $VOX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "예약 확인 플로우", "type": "flow", "flow": { "nodes": [ { "id": "begin", "type": "begin", "position": { "x": 0, "y": 0 }, "data": { "name": "시작", "first_line_type": "aiFirst" } }, { "id": "confirm", "type": "conversation", "position": { "x": 360, "y": 0 }, "data": { "name": "예약 확인", "prompt_type": "dynamic", "prompt": "예약 정보를 확인하고 변경이 필요한지 물어보세요." } }, { "id": "end", "type": "endCall", "position": { "x": 720, "y": 0 }, "data": { "name": "종료", "prompt_type": "static", "static_sentence": "확인했습니다. 감사합니다." } } ], "edges": [ { "source": "begin", "target": "confirm", "condition": { "type": "fallback" } }, { "source": "confirm", "target": "end", "condition": { "type": "ai", "prompt": "사용자가 예약 확인을 마쳤을 때" } } ] } }' ``` ## 전환 조건 `edge.condition`은 `type`으로 구분해요. 자연어 조건이에요. 사용자의 발화와 지금 대화 맥락을 보고 다음 노드로 이동할지 판단해요. ```json theme={null} { "type": "ai", "prompt": "사용자가 상담원 연결을 요청했을 때" } ``` 조건 노드에서 변수 값을 비교할 때 써요. `equations`는 하나 이상이어야 해요. ```json theme={null} { "type": "logic", "operator": "&&", "equations": [ { "left": "reservation_status", "operator": "equals", "right": "confirmed" } ] } ``` 같은 source 노드의 다른 조건이 맞지 않을 때 이동하는 기본 경로예요. ```json theme={null} { "type": "fallback" } ``` ## 글로벌 노드 글로벌 노드는 전환이 아니라 노드에 표시해요. `node.data.global_node_setting`이 있으면 글로벌 노드로 처리해요. `global_node_setting`은 `conversation`, `sendSms`, `endCall` 노드에서만 허용해요. 다른 노드 타입에 넣으면 저장이 거부돼요. 웹 빌더도 이 세 타입에서만 글로벌 노드를 지원해요. ```json theme={null} { "id": "human-help", "type": "conversation", "position": { "x": 360, "y": 240 }, "data": { "name": "상담원 연결 안내", "prompt_type": "dynamic", "prompt": "상담원 연결 절차를 안내하세요.", "global_node_setting": { "condition": { "type": "ai", "prompt": "사용자가 사람 상담원을 원할 때" } } } } ``` 글로벌 노드의 조건은 `ai`만 지원해요. `logic`이나 `fallback`은 저장할 수 없어요. ## 저장 검증 `flow`를 저장할 때는 자동 수정 없이 검증해요. 불완전한 그래프를 서버가 추측해서 고치지 않으니 그래프를 완성해서 보내세요. 같은 `flow` 그래프를 저장하지 않고 미리 검증하려면 `POST /v3/agents/validate-flow`를 호출하세요. ```bash theme={null} curl "https://client-api.tryvox.co/v3/agents/validate-flow?level=all" \ -H "Authorization: Bearer $VOX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "flow": { "nodes": [ { "id": "begin", "type": "begin", "position": { "x": 0, "y": 0 }, "data": { "name": "시작", "first_line_type": "aiFirst" } }, { "id": "end", "type": "endCall", "position": { "x": 320, "y": 0 }, "data": { "name": "종료" } } ], "edges": [ { "source": "begin", "target": "end", "condition": { "type": "fallback" } } ] } }' ``` | 응답 필드 | 의미 | | - | - | | `valid` | 저장을 막는 치명적 오류가 없으면 `true` | | `errors` | 저장을 막는 치명적 오류 목록 | | `advisories` | 저장은 되지만 실행 중 동작이 예상과 달라질 수 있는 런타임 주의 항목 목록 | `validate-flow`는 저장하지 않고 검증해서, 형식이 잘못된 `flow`도 일반 에러 응답 대신 `valid=false` 엔벨로프로 돌려줘요. 예를 들어 `position` 누락, 잘못된 `condition.type`, 지원하지 않는 `logic` 연산자는 `errors[].code = "flow_v2_schema_invalid"`로 돌아와요. `level` 쿼리로 응답에 담을 항목 범위를 정할 수 있어요. | `level` | 반환 내용 | | - | - | | `critical` | 기본값. 저장을 막는 `errors`만 돌려줘요 | | `runtime` | `advisories`만 돌려줘요. `valid`는 치명적 오류 여부를 계속 반영해요 | | `all` | `errors`와 `advisories`를 모두 돌려줘요 | 치명적 오류가 있는 그래프라도 변환할 수 있으면 런타임 주의 항목을 함께 돌려줘요. 그래서 `level=runtime`에서는 `errors`가 비어 있어도 `valid=false`일 수 있어요. `level=all`에서는 저장을 막는 오류와 런타임 주의 항목을 함께 확인할 수 있어요. 런타임 주의 항목에는 연결되지 않은 skip·fallback 전환, begin에서 도달할 수 있는 종료 노드가 없는 경우가 들어가요. 저장은 막지 않지만 실제 통화에 쓰기 전에 고치세요. 도구, 지식 베이스, 파일, 다른 에이전트 이관처럼 외부 리소스를 참조하는 필드는 값을 보냈다면 실제로 있는지와 워크스페이스 접근 권한을 검증해요. 비어 있는 참조는 작성 중인 초안으로 저장할 수 있지만, 잘못된 ID나 다른 워크스페이스의 ID는 저장이 거부돼요. 런타임 주의 항목이 있는 그래프도 이 참조 검증은 거쳐요. | 상황 | 결과 | | - | - | | `nodes` 또는 `edges` 누락 | 저장 거부 | | `position` 누락 | 저장 거부 | | `begin.data.first_line_type` 누락 | 저장 거부 | | `begin` 노드가 0개 또는 2개 이상 | 저장 거부 | | `begin` 노드에 `fallback` 전환 없음 | 저장 거부 | | `begin`에서 `fallback`이 아닌 조건 사용 | 저장 거부 | | `begin`에서 `skip_user_response=true` 사용 | 저장 거부 | | 전환의 `source` 또는 `target`이 존재하지 않는 노드 ID | 저장 거부 | | 노드 ID 또는 전환 ID 중복 | 저장 거부 | | `logic` 전환이 조건 노드가 아닌 곳에서 출발 | 저장 거부 | | `logic` 조건의 `equations`가 비어 있음 | 저장 거부 | | 지원하지 않는 `logic` 연산자 사용 | 저장 거부 | | `source`별 `fallback` 전환이 2개 이상 | 저장 거부 | | 같은 `source`에 같은 조건 전환이 2개 이상 | 저장 거부 | | `global_node_setting`이 객체가 아니거나 비어 있거나 `ai` 조건이 아님 | 저장 거부 | | `conversation`/`sendSms`/`endCall`이 아닌 노드에 `global_node_setting` 포함 | 저장 거부 | | `note` 노드에 연결된 전환(`source` 또는 `target`이 note) | 저장 거부 | | `transitions`, `logicalTransitions`, `logical_transitions`, `globalNodeSettings`, `global_node_settings` 포함 | 저장 거부 | | 문서화되지 않은 `nodes[].data` 최상위 키 포함 | 저장 거부 | | 제공한 도구, 지식 베이스, 파일, 이관 대상 에이전트 참조가 없거나 접근 불가 | 저장 거부 | | `function` 또는 기존 `knowledge` 노드 포함 | `flow` 쓰기 거부 | 오래된 그래프를 조회하면 `flow`에 보이지 않는 빌더 내부 분기가 있을 수 있어요. 이런 그래프는 `flow`로 다시 저장할 때 거부될 수 있으니, 기존 빌더 형태를 정리한 뒤 다시 저장하세요. ## 지원 종료 예정 경로 새 통합에서는 아래 경로를 쓰지 마세요. * `flow_data`: 기존 빌더 그래프예요. 읽기와 쓰기는 호환용으로만 유지해요. * `POST /v3/agents/validate-flow-data`: `flow_data` 전용 검증이에요. `flow` 검증은 `POST /v3/agents/validate-flow`를 쓰세요. * `POST /v3/agents/autofix-flow-data`: `flow_data` 보정 도구예요. * `POST /v3/flow-data/autofix`: `flow_data` 보정 도구예요. * `sourceHandle`, `targetHandle`, `transitions`, `logicalTransitions`, `globalNodeSettings`: `flow` 작성에는 쓰지 않아요. ## 마이그레이션 `GET /v3/agents/{agent_id}` 응답에서 `flow_data` 대신 `flow`를 읽으세요. `POST /v3/agents`와 `PATCH /v3/agents/{agent_id}`에서 `flow`를 보내고 `flow_data`는 보내지 마세요. `validate-flow-data`와 `autofix-flow-data` 호출을 없애세요. 저장 전에 검증하려면 `POST /v3/agents/validate-flow`를 쓰세요. `sourceHandle`, `transitions`, `globalNodeSettings` 같은 내부 키를 없애고 `edges[].condition`과 `global_node_setting`으로 바꾸세요. `firstLineType`, `promptType`, `apiConfiguration` 같은 키를 `first_line_type`, `prompt_type`, `api_configuration`으로 바꾸세요. ## LLM 작성 체크리스트 LLM이나 MCP 클라이언트가 `flow`를 직접 작성할 때는 아래 순서로 payload를 조립하세요. 1. `flow_data` 대신 `flow`만 쓰세요. 2. 모든 노드에 `id`, `type`, `position`을 넣으세요. 3. begin 노드에는 `data.first_line_type`을 넣고, begin에서 나가는 전환은 `fallback` 하나로 두세요. 4. 전환은 `edges[].condition.type`을 `ai`, `logic`, `fallback` 가운데 하나로 표현하세요. 5. `logic` 조건은 조건 노드에서만 시작하게 하고, `equations`를 하나 이상 넣으세요. 6. `node.data`에는 snake\_case 키만 쓰세요. 7. `node.data`에는 `transitions`, `logicalTransitions`, `globalNodeSettings`를 넣지 마세요. 8. 저장하기 전에 `POST /v3/agents/validate-flow?level=all`을 호출해 `errors`를 모두 해결하세요. 9. 프롬프트만 수정할 때는 기존 `data.builtInTools` 값을 유지하세요. 기본 도구 목록을 다시 만들지 마세요. 10. Flow 에이전트는 `pipeline` 런타임만 써요. `runtime.type`에 `"gpt_live"`, `"grok_voice"`, `"gemini_live"`를 보내지 마세요. 기존 Flow를 수정할 때 `flow.nodes[].data.llm` 노드별 LLM 설정은 보존하지만 네이티브 실시간 기능으로 해석하지 않아요. ## 관련 문서 * [전환 조건](/docs/build/flow/transitions): 대시보드에서 전환 조건 설계하기 * [API 참조 소개](/api-reference/v3/introduction): 에이전트를 만들고 수정하는 엔드포인트의 전체 스키마 보기 # API 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/api-node 플로우의 정해진 지점에서 주문을 조회하거나 예약을 접수하고, 응답 값을 다음 안내에 쓸 수 있어요. API 노드는 플로우가 도착하면 바로 HTTP 요청을 보내요. 고객의 답은 기다리지 않고, 요청 결과에 맞는 다음 노드로 넘어가요. 주문 상태 조회 API 노드에서 배송 상태 안내와 조회 실패 안내로 연결한 플로우 요청은 노드 안에서 직접 설정해요. 이미 등록한 API 도구를 쓰려면 [도구 노드](/docs/build/flow/nodes/tool-node)를 쓰세요. ## 언제 사용하나요 * **주문 상태를 안내할 때**: 주문 번호로 조회하고, 응답에서 배송 상태와 도착 예정일을 꺼내 안내해요. * **예약을 접수할 때**: 수집한 날짜와 인원수를 보내고, 응답의 예약 번호로 접수 결과를 안내해요. * **상담 결과를 저장할 때**: 고객 식별자와 상담 내용을 보내요. 저장 결과가 다음 안내에 필요 없다면 응답을 기다리지 않아도 돼요. ## 노드 설정하기 아래 단계는 주문 상태를 조회하는 노드를 예로 들어요. 앞 단계에서 `order_id` 변수를 준비해 두세요. 화면 아래에서 **API** 노드를 추가하고, 앞 노드의 전환 조건을 이 노드에 연결하세요. 노드를 선택하고 **API 설정**의 **엔드포인트**에서 메서드와 URL을 정하세요. URL에는 `https://api.example.com/orders/{{order_id}}`처럼 변수를 넣을 수 있어요. 예약 접수처럼 본문이 필요하면 **POST**를 고르고 **Body**를 켜서 요청 JSON을 쓰세요. 인증과 헤더는 연결할 API의 요구에 맞추세요. API 노드 설정 패널의 요청 URL과 응답 변수 추출 설정 **프롬프트**에서 **정적**을 고르고 `주문 내역을 확인해 드릴게요.` 같은 안내를 적으세요. 상황에 맞춰 말하게 하려면 **동적**, 안내가 필요 없으면 **없음**을 고르세요. 조회 결과를 쓸 때는 **응답 대기 방식**을 기본값인 **결과 기다리기**로 두세요. **응답 타임아웃**은 기본 10초이니 API의 처리 시간에 맞춰 조정하세요. 기다리는 동안 들려줄 소리는 **실행 중 대기음**에서 골라요. 자세한 동작은 [실행 대기음](/docs/build/tools/tool-call-sound)에 있어요. **응답 변수 추출**에서 **응답 변수 추가**를 누르고, 저장할 변수명과 값을 찾을 JSONPath를 넣으세요. 예시에서는 `order_status`에 `$.data.status`, `delivery_date`에 `$.data.delivery_date`를 지정해요. `주문 상태를 조회한 경우` 같은 전환 조건을 추가해 결과를 안내할 노드에 연결하세요. **요청 실패 시**에는 조회 실패를 안내할 노드를 연결하세요. 응답 값에 따라 나누려면 [전환 조건](/docs/build/flow/transitions)을 참고하세요. 예시의 주문 조회 API가 아래처럼 응답하면 `order_status`에는 「배송 중」, `delivery_date`에는 「9월 28일」이 저장돼요. 예시 URL은 실제 주문 조회 API 주소로 바꾸세요. ```text 요청 URL theme={null} https://api.example.com/orders/{{order_id}} ``` ```json 응답 예시 theme={null} { "data": { "status": "배송 중", "delivery_date": "9월 28일" } } ``` 다음 대화 노드의 **정적** 안내에 `주문은 {{order_status}} 상태입니다. {{delivery_date}} 도착 예정입니다.`를 넣으면 고객은 "주문은 배송 중 상태입니다. 9월 28일 도착 예정입니다."를 들어요. 변수 문법은 [동적 변수](/docs/build/variables/dynamic-variables)에 있어요. ## 통화에서 일어나는 일 노드에 도착하면 안내와 요청을 함께 시작해요. 안내를 마칠 때까지 요청을 미루지 않으니, 이번 응답으로 받은 값은 다음 노드에서 안내하세요. 그다음은 **응답 대기 방식**에 따라 달라져요. 안내와 요청이 모두 끝나야 다음 노드로 넘어가요. 응답이 늦으면 고객은 안내 뒤에 잠시 기다려요. * 응답 변수를 반영한 뒤 다음 경로를 판단해요. 다음 노드에서 응답 값을 안내할 수 있어요. * HTTP 2xx는 성공으로 처리해요. 요청 오류나 타임아웃은 **요청 실패 시** 경로로 이어져요. * JSONPath에 맞는 값이 없거나 null이면 빈 문자열을 저장해요. 요청이 성공해도 필요한 값이 비어 있을 수 있어요. 조회 결과를 안내하거나 응답 값으로 분기할 때 고르세요. 안내가 끝나는 대로 다음 노드로 넘어가요. 요청은 뒤에서 계속 진행돼요. * 응답 변수를 추출하지 않아요. 이 방식에서는 응답 변수를 설정할 수 없어요. * 뒤늦게 요청이 실패해도 **요청 실패 시** 경로로 돌아가지 않아요. 상담 결과 저장처럼 응답을 다음 안내에 쓰지 않을 때 고르세요. ## 관련 문서 노드를 추가하고 앞뒤 노드와 연결할 수 있어요. 요청에 넣거나 다음 안내에서 쓸 변수를 준비할 수 있어요. 등록해 둔 API 도구를 플로우에서 실행할 수 있어요. # 시작 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/begin-node 플로우를 고객의 용건부터 들을지, 에이전트의 안내로 시작할지 정할 수 있어요. 시작 노드에서는 누가 먼저 말할지만 정해요. 시작 노드에 연결한 노드가 첫 실행 노드이고, 인사 내용은 그 [대화 노드](/docs/build/flow/nodes/conversation-node)에 적어요. 시작 노드와 첫 대화 노드의 연결, 오른쪽 대화 시작과 첫 발화 전 대기 시간 설정 ## 언제 사용하나요 * **고객의 용건부터 들을 때**: 고객이 먼저 말하도록 설정해요. * **발신 목적부터 안내할 때**: 에이전트가 먼저 말하도록 설정해요. * **첫 안내를 잠시 늦출 때**: 첫 안내 전 대기 시간을 조정해요. ## 노드 설정하기 플로우 편집기에서 시작 노드를 선택하세요. 오른쪽 패널에 **대화 시작**이 보여요. **사용자부터**나 **AI부터**를 고르세요. **AI부터**를 고르면 **첫 발화 전 대기 시간**을 0\~5초 사이로 조정할 수 있어요. 시작 노드에는 인사 문구 입력란이 없어요. 시작 노드 오른쪽 연결점을 첫 실행 노드에 이으세요. 인사로 시작하려면 대화 노드를 연결하고, 인사 문구와 지시는 그 대화 노드에 적으세요. 노드를 추가하고 잇는 방법은 [노드 개요](/docs/build/flow/nodes/overview)에 있어요. ## 통화에서 일어나는 일 * **시작 방식은 시작 노드 설정을 따라요.** 사용자부터를 고르면 고객의 말을 기다리고, AI부터를 고르면 첫 실행 노드부터 진행해요. * **대기 시간도 시작 노드 값이 먼저예요.** 플로우의 첫 안내 시점은 여기서 조정하세요. * **첫 인사의 끼어들기는 첫 실행 노드 설정을 따라요.** 대화 노드로 시작한다면 그 노드의 **말 끼어들기 허용**에서 조정하세요. 시작 방식을 고르는 기준과 대기 중에 고객이 말할 때의 동작은 [첫 메시지](/docs/build/conversation/first-message)에 있어요. 그 문서는 프롬프트 에이전트 화면을 기준으로 설명해요. ## 관련 문서 프롬프트 에이전트의 시작 방식과 첫 인사 동작을 확인할 수 있어요. 플로우의 인사 문구와 노드별 끼어들기를 설정할 수 있어요. 노드를 추가하고 앞뒤 노드와 연결할 수 있어요. # 조건 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/condition-node 변수 값을 비교해 문의 유형이나 조회 결과에 맞는 안내로 연결할 수 있어요. 조건 노드는 지금 변수 값에 맞는 다음 경로를 골라요. 고객에게 말하지 않고 새 답도 기다리지 않아요. 문의 유형이나 조회 결과에 따라 안내를 나눌 때 쓰세요. 문의 유형이 예약 변경이면 예약 변경 안내로, Else이면 일반 문의 안내로 연결한 플로우 고객에게 질문하려면 [대화 노드](/docs/build/flow/nodes/conversation-node)를 쓰고, 답에서 값을 얻으려면 [추출 노드](/docs/build/flow/nodes/extraction-node)를 먼저 두세요. ## 언제 사용하나요 * **문의 유형을 나눌 때**: 추출한 문의 유형에 맞는 안내로 연결해요. * **조회 결과를 안내할 때**: API 응답 값에 맞춰 경로를 골라요. * **필수 값이 빠졌을 때**: 다시 묻는 경로로 연결해요. 통화 시작 때 받은 변수와 통화 중에 얻은 변수를 함께 비교할 수 있어요. 이름이 같으면 통화 중에 얻은 값으로 비교해요. ## 노드 설정하기 예시에서는 문의 유형을 `inquiry_type`에 저장하고, 예약을 바꾸려는 고객의 값을 `예약 변경`으로 정해요. 통화 시작 때 값을 넣으려면 [동적 변수](/docs/build/variables/dynamic-variables)를, 대화에서 얻는 값은 [추출 노드](/docs/build/flow/nodes/extraction-node)를, 조회 결과는 [API 노드](/docs/build/flow/nodes/api-node)의 응답 변수를 쓰세요. 조건 노드를 추가하고 앞 노드와 연결하세요. 노드의 **조건부 전환** 옆 \*\*+\*\*를 누르고, 추가한 행을 눌러 **조건 편집**을 여세요. **추가**를 누른 뒤 변수, 연산자, 값을 정하고 **저장**을 누르세요. 예시에서는 `inquiry_type`, 같음 (=), `예약 변경`을 골라요. 조건 편집 창에서 inquiry_type이 예약 변경과 같은지 비교하는 설정 한 분기에서 여러 값을 비교할 수 있어요. **논리 연산자**의 기본값은 **OR**이고, 모든 조건을 만족해야 하면 **AND**로 바꾸세요. 여러 분기가 겹치면 먼저 보낼 분기를 위에 두세요. 행 왼쪽 손잡이를 끌어 순서를 바꿀 수 있어요. 예약 변경 조건의 연결점을 예약 변경 안내 노드에 이으세요. **Else**는 자동으로 생기니, 예시에서는 일반 문의 안내 노드에 연결하세요. 조건에 맞는 값, 맞지 않는 값, 빈 값으로 각각 테스트하세요. 비교 연산자는 아래에서 골라요. 존재 여부를 보는 연산자는 비교 값을 넣지 않아요. 크기를 비교하는 연산자는 두 값이 숫자면 숫자로 비교해요. | 화면의 연산자 | 맞는 경우 | | - | - | | 같음 (=) | 변수와 비교 값이 같음 | | 같지 않음 (≠) | 변수와 비교 값이 다름 | | 보다 큼 (>) | 변수가 비교 값보다 큼 | | 보다 작음 (\<) | 변수가 비교 값보다 작음 | | 보다 크거나 같음 (≥) | 변수가 비교 값보다 크거나 같음 | | 보다 작거나 같음 (≤) | 변수가 비교 값보다 작거나 같음 | | 포함 (∈) | 변수에 비교할 텍스트가 들어 있음 | | 미포함 (∉) | 변수에 비교할 텍스트가 들어 있지 않음 | | 존재함 (∃) | 변수가 미설정, `null`, 빈 문자열이 아님 | | 존재하지 않음 (¬∃) | 변수가 미설정, `null`, 빈 문자열임 | 한 분기 안의 조건은 아래 규칙으로 묶여요. | 논리 연산자 | 분기를 고르는 기준 | | - | - | | AND | 모든 조건이 맞아야 함 | | OR | 하나 이상의 조건이 맞으면 됨 | ## 통화에서 일어나는 일 * **목록의 위에서부터 비교해요.** 처음 맞는 분기를 골라요. * **여러 분기가 맞아도 하나만 골라요.** 아래 분기로 함께 보내지 않아요. * **모든 조건이 맞지 않으면 Else를 골라요.** 연결한 노드에서 다음 처리를 이어가요. ## 문제가 생겼을 때 겹치는 조건과 분기 순서를 확인하고, 먼저 처리할 분기를 위로 옮기세요. 여러 조건이 맞으면 위에 있는 분기가 먼저예요. 변수에 공백만 들어 있는지 확인하고, 값을 만드는 단계에서 불필요한 공백을 지우세요. 공백 문자열은 빈 문자열과 달라요. 실제 변수 값과 비교 값의 표기를 맞추세요. 같음은 양쪽을 문자열로 바꿔 비교해서 대소문자와 앞뒤 공백까지 같아야 해요. Else의 연결점이 다음 노드로 이어지는지 확인하세요. Else 행이 있어도 목적지는 따로 연결해야 해요. ## 관련 문서 노드를 추가하고 앞뒤 경로를 연결할 수 있어요. 통화 시작 때 비교할 값을 넘길 수 있어요. 고객의 답을 변수로 저장할 수 있어요. 조회 결과를 변수로 저장할 수 있어요. # 대화 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/conversation-node 고객에게 필요한 정보를 묻고, 답에 따라 다음 단계로 안내할 수 있어요. 대화 노드는 고객에게 묻고 답을 들은 뒤, 조건에 맞는 다음 노드로 넘겨요. 필요한 정보를 다 받을 때까지 한 노드에서 여러 번 묻고 답할 수 있고, 안내만 하고 바로 넘어가게 할 수도 있어요. 예약 정보 수집 대화 노드의 완료 및 거절 경로와 오른쪽 설정 패널 대화 노드는 도구를 호출하지 않아요. 외부 작업은 [도구 노드](/docs/build/flow/nodes/tool-node)로 연결하세요. ## 언제 사용하나요 * **고객의 용건을 확인할 때**: 문의를 듣고 담당 업무로 나눠요. * **예약 정보를 모을 때**: 이름과 희망 일시를 묻고, 빠진 정보만 다시 받아요. * **답을 기다리지 않는 안내를 할 때**: 안내를 마친 뒤 다음 단계로 넘겨요. ## 노드 설정하기 아래 단계는 예약 정보를 모으는 노드를 예로 들어요. **대화** 노드를 추가하고 앞 노드와 연결하세요. 추가 방법과 노드를 나누는 기준은 [노드 개요](/docs/build/flow/nodes/overview)에 있어요. 고객의 답에 맞춰 질문하려면 **동적**을 고르고, **프롬프트**에 받을 정보와 질문 방식을 적으세요. **첫 메시지**를 넣으면 처음에는 그 문장을 말하고, 이후에는 프롬프트에 따라 답해요. 정해진 문장을 그대로 읽으려면 **정적**을 고르세요. 정적은 같은 노드에 머무는 동안 그 문장을 되풀이해요. ```text theme={null} 고객의 이름, 희망 예약 날짜와 시간을 확인하세요. 한 번에 한 가지씩 묻고, 이미 받은 정보는 다시 묻지 마세요. 답이 모호하면 필요한 정보만 다시 질문하세요. 예약을 원하지 않으면 추가 질문을 멈추세요. 예약이 확정됐다고 안내하지 마세요. ``` 이 대화에 필요한 지식을 노드의 **지식 베이스**에 연결하세요. 지식을 준비하는 방법은 [지식 베이스 개요](/docs/build/knowledge/overview)에 있어요. **반복 조건**에는 다음으로 넘어가도 되는 상황을 적으세요. 조건을 채우지 못하면 일반 전환이 막혀요. 정보를 다 받은 경우뿐 아니라 고객이 거절한 경우도 넣으세요. ```text theme={null} 다음 중 하나를 충족하면 다음 노드로 이동할 수 있습니다. - 고객의 이름, 희망 예약 날짜와 시간을 모두 확인했습니다. - 고객이 예약을 원하지 않는다고 명확히 말했습니다. ``` **전환 조건**을 목적지마다 하나씩 추가하고 다음 노드에 연결하세요. 예시에서는 `고객의 이름과 희망 일시를 모두 확인했고 예약을 원합니다.`를 예약 내용 확인 노드에, `고객이 예약을 원하지 않는다고 명확히 말했습니다.`를 종료 안내 노드에 이어요. 날짜만 답한 경우, 정보를 모두 답한 경우, 거절한 경우를 각각 테스트하세요. 조건 쓰는 법은 [전환 조건](/docs/build/flow/transitions)에 있어요. **유저 응답 건너뛰기**는 기본으로 꺼져 있어요. 안내만 하는 노드에서 켜고 다음 노드와 연결하세요. **말 끼어들기 허용**은 기본으로 켜져 있어요. ## 통화에서 일어나는 일 * **고객의 답을 듣고 조건을 판단해요.** 반복 조건을 통과하고 전환 조건도 맞으면 다음 노드로 이동해요. * **맞는 경로가 없으면 같은 노드에 머물러요.** 프롬프트에 따라 대화를 이어가요. * **유저 응답 건너뛰기를 켜면 말한 뒤 바로 이동해요.** 이 경로에서는 고객의 답과 반복 조건을 기다리지 않으니, 답을 받아야 하는 노드에서는 꺼 두세요. ## 문제가 생겼을 때 답에 맞춰 질문하려면 동적으로 바꾸세요. 정적은 같은 노드에 머무는 동안 고정 문장을 되풀이해요. 반복 조건에 거절 상황도 넣으세요. 거절 경로를 연결해도 반복 조건을 통과하지 못하면 이동하지 않아요. 유저 응답 건너뛰기를 끄세요. 켜져 있으면 말을 마친 뒤 연결된 노드로 이동해요. ## 관련 문서 여러 노드에서 공통 문의로 넘어가는 경로를 만들 수 있어요. 고객이 전화 키패드로 답을 입력하게 할 수 있어요. # 종료 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/end-node 상담을 마친 고객에게 마지막 인사를 전하고 통화를 끝낼 수 있어요. 종료 노드는 마지막 안내를 마친 뒤 통화를 끊어요. 고객의 답을 기다리지 않으니 상담을 마무리할 지점에 연결하세요. 상담 완료와 고객 거절 조건을 각각 종료 노드에 연결한 플로우 프롬프트 에이전트에서 에이전트가 끝낼 때를 판단하게 하려면 [통화 종료 도구](/docs/build/tools/builtin/end-call)를 쓰세요. ## 언제 사용하나요 * **상담을 마쳤을 때**: 처리 결과를 알리고 감사 인사로 마무리해요. * **고객이 상담을 거절했을 때**: 더 권하지 않고 통화를 마쳐요. * **본인 확인에 실패했을 때**: 진행할 수 없는 이유를 알리고 끝내요. 종료 사유마다 안내가 다르면 노드를 따로 두세요. 상담 완료에는 `이용해 주셔서 감사합니다.`, 거절에는 `알겠습니다. 통화를 마치겠습니다.`처럼 적을 수 있어요. ## 노드 설정하기 화면 아래에서 **통화 종료**를 추가하고, 앞 노드의 [전환 조건](/docs/build/flow/transitions)을 연결하세요. 조건은 `고객의 문의를 해결했고 추가 문의가 없는 경우`처럼 적어요. 공통 조작은 [노드 개요](/docs/build/flow/nodes/overview)에 있어요. 종료 노드를 선택하고 **프롬프트**를 정하세요. 화면 아래에서 새로 추가하면 **동적**이 기본값이에요. * **정적**: 입력한 문구를 그대로 말해요. 늘 같은 마지막 인사를 할 때 고르세요. * **동적**: 프롬프트에 따라 안내를 만들어요. `상담 결과를 짧게 정리하고 감사 인사를 하세요.`처럼 적으세요. * **없음**: 이 노드의 안내를 생략해요. 앞 노드에서 마지막 인사까지 마쳤을 때 고르세요. 종료 노드 설정에서 정적을 고르고 마지막 인사를 입력한 패널 고객의 답이 필요한 질문은 앞 대화 노드에 두고, 답을 확인한 뒤 종료 노드로 연결하세요. **정적** 문구도 질문 없이 마무리하세요. 종료 뒤에 이어갈 전환 조건은 추가하지 않아요. 여러 대화에서 같은 거절 조건을 쓰려면 **글로벌 노드**를 켜고, **전환 조건**에 `고객이 상담을 원하지 않는다고 명확히 말한 경우`처럼 거절 상황을 구체적으로 적으세요. 글로벌 지정은 선택이고, 방법은 [글로벌 노드](/docs/build/flow/advanced/global-node)에 있어요. ## 통화에서 일어나는 일 마지막 인사 중 고객이 말해도 안내를 계속하고 재생이 끝난 뒤 통화를 끊는 모습 * **안내를 마친 뒤 끊어요.** 정상 동작에서는 음성 재생이 끝날 때까지 기다려요. * **고객이 말해도 종료를 취소하지 않아요.** 플로우 종료 노드는 끼어들기를 허용하지 않아서, 마지막 인사 중 고객이 말해도 안내를 계속해요. * **글로벌로 들어와도 종료 동작은 같아요.** 마지막 안내 뒤 통화를 끊고 답을 기다리지 않아요. ## 문제가 생겼을 때 질문을 앞 대화 노드로 옮기고, 추가 문의가 없다는 답을 확인한 뒤 종료하세요. 종료 노드는 고객의 답을 받지 않아요. 프롬프트 선택과 안내 내용을 확인하세요. 없음은 이 노드의 안내를 생략하고, 정적을 골랐다면 고객에게 들려줄 문구가 있어야 해요. API나 도구 처리 뒤의 종료 경로도 따로 연결하세요. 글로벌 종료는 모든 처리를 바로 멈추지 않아요. 시작, 종료, 통화 전환, API, 도구, 조건, 추출, 문자 발신 노드는 자동 연결 대상이 아니에요. ## 관련 문서 프롬프트 에이전트가 끝낼 때를 스스로 판단하게 할 수 있어요. 종료 노드로 넘어갈 상황을 정할 수 있어요. 고객의 답을 확인한 뒤 종료로 넘길 수 있어요. # 추출 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/extraction-node 고객이 말한 이름, 전화번호, 날짜 같은 정보를 변수로 저장해 다음 노드에서 쓸 수 있어요. 추출 노드는 지금까지의 대화에서 정해 둔 정보를 꺼내 변수로 저장해요. 고객에게 말하지 않고 답도 기다리지 않으며, 저장이 끝나면 바로 다음 노드로 넘어가요. 추출 노드의 프롬프트와 보증기간 여부를 저장하는 불리언 변수 정의 저장한 값으로 경로를 나누려면 뒤에 [조건 노드](/docs/build/flow/nodes/condition-node)를 두세요. ## 언제 사용하나요 * **이름, 전화번호, 주소를 남길 때**: 고객이 말한 정보를 변수로 저장해 다음 노드에서 써요. * **말한 값을 정해진 형식으로 바꿀 때**: "시월 십칠일"을 `2025-10-17`처럼 바꿔 저장해요. * **다음 노드에서 값으로 판단할 때**: 조건 노드의 분기나 API 노드의 요청에 넣어요. * **여러 항목을 한 번에 받을 때**: 상품명, 배송일시, 배송 장소를 한 노드에서 저장해요. ## 노드 설정하기 화면 아래에서 **추출** 노드를 추가하고, 정보를 물어본 대화 노드 뒤에 연결하세요. **프롬프트**에 무엇을 어떤 형식으로 뽑을지 적으세요. 추출 노드의 프롬프트는 **동적** 하나이고, 비워 두면 기본 프롬프트를 써요. 숫자로 바꿔야 하는 값은 변환 규칙과 예시를 함께 적으면 정확해져요. ```text theme={null} 고객이 말한 성함과 전화번호를 추출하세요. - 전화번호는 한국어 발음을 숫자로 변환합니다. 예: "공일공 이삼사오 육칠팔구" → "01023456789" - 성함은 한글 그대로 추출합니다. ``` **변수 정의**에서 **추가**를 누르고 타입, 변수명, 설명을 넣으세요. 타입은 **문자열**, **숫자**, **불리언** 가운데 골라요. 설명은 에이전트가 어떤 값을 뽑을지 판단하는 데 쓰여요. 예시에서는 `customer_name`(문자열, 고객 성함)과 `phone_number`(문자열, 숫자만 쓴 전화번호)를 정의해요. 이 노드만 다른 모델을 쓰려면 **노드 LLM 설정**을 켜고 모델을 고르세요. 켜지 않으면 에이전트 전체 모델을 써요. 추출하는 동안 들려줄 소리는 **실행 중 대기음**에서 고르고, 기본값은 **소리 없음**이에요. 자세한 동작은 [실행 대기음](/docs/build/tools/tool-call-sound)에 있어요. 전환 조건을 추가해 다음 노드에 연결하세요. 저장한 변수는 다른 노드에서 `{{customer_name}}`처럼 써요. 날짜와 시간은 형식을 정해 두면 조건 노드나 API 노드에서 바로 쓸 수 있어요. 아래는 배송일시를 받는 예시예요. 변수는 `delivery_date`와 `delivery_time`을 문자열로 정의해요. ```text theme={null} 고객이 말한 배송 날짜와 시간을 추출하세요. - 날짜는 YYYY-MM-DD 형식으로 변환합니다. 예: "시월 십칠일" → "2025-10-17" - 시간은 HH:MM 형식으로 변환합니다. 예: "열두시 반" → "12:30" ``` ## 통화에서 일어나는 일 * **고객에게 말하지 않아요.** 추출 노드는 늘 사용자 응답을 건너뛰고, 추출이 끝나면 바로 다음 노드로 넘어가요. * **통화 처음부터의 대화에서 값을 찾아요.** 바로 앞의 답만 보지 않아요. * **대화에 없는 값은 비어 있을 수 있어요.** 추출은 대화에 나온 값만 저장해요. 뒤의 조건 노드에서 빈 값을 걸러 내세요. * **저장한 변수는 이후 노드에서 모두 쓸 수 있어요.** 프롬프트, 안내 문구, 조건, API 요청에서 `{{변수명}}`으로 참조해요. ## 문제가 생겼을 때 앞 대화 노드에서 그 정보를 실제로 묻고 답을 받았는지 확인하세요. 추출 노드는 대화에 나온 값만 저장해요. 추출 프롬프트에 변환 규칙과 예시를 적으세요. 규칙이 없으면 고객이 말한 표현이 그대로 저장될 수 있어요. ## 관련 문서 노드를 추가하고 앞뒤 노드와 연결할 수 있어요. 추출한 변수를 프롬프트와 안내에서 쓸 수 있어요. 추출한 변수로 대화 경로를 나눌 수 있어요. # 노드 개요 Source: https://docs.tryvox.co/docs/build/flow/nodes/overview 플로우를 노드로 나누고 전환 조건으로 이어, 단계마다 에이전트가 할 일을 정할 수 있어요. 노드는 플로우의 한 단계예요. 노드마다 에이전트가 할 일을 정하고, 전환 조건으로 다음 노드와 이어요. 플로우 편집기의 노드 유형별 추가 버튼과 메모, 자동 정렬 메뉴 ## 고객과 대화하기 누가 먼저 말할지 정할 수 있어요. 모든 플로우에 하나씩 있어요. 고객에게 묻고 답을 들은 뒤 다음 단계로 넘길 수 있어요. 마지막 인사를 하고 통화를 끝낼 수 있어요. ## 값 저장하고 경로 나누기 고객이 말한 정보를 변수로 저장할 수 있어요. 변수 값을 비교해 경로를 나눌 수 있어요. ## 외부 작업 실행하기 노드 안에서 HTTP 요청을 보내고 응답 값을 저장할 수 있어요. 등록해 둔 API 도구를 정해진 지점에서 실행할 수 있어요. 고객에게 문자를 보내고 결과에 따라 다음 안내를 정할 수 있어요. ## 통화 넘기기 상담사 번호나 외부 번호로 통화를 넘길 수 있어요. 같은 워크스페이스의 다른 에이전트에게 응대를 넘길 수 있어요. ## 노드 추가하고 연결하기 화면 아래 플로팅 패널에서 노드 아이콘을 누르면 캔버스에 노드가 생겨요. 노드를 누르면 오른쪽 패널에 그 노드의 설정이 열리고, 빈 캔버스를 누르면 에이전트 전체 설정이 열려요. 플로우 편집기 아래 플로팅 패널의 노드 추가 버튼들 노드 아래 **전환 조건** 옆 \*\*+\*\*로 조건을 추가하고, 조건 오른쪽의 원형 연결점을 끌어 다음 노드에 이으세요. 시작 노드에서 적어도 한 노드로 이어야 대화가 시작돼요. 조건 쓰는 법은 [전환 조건](/docs/build/flow/transitions)에 있어요. 플로팅 패널의 메모 버튼으로 캔버스에 설명을 남길 수 있어요. 메모는 통화에서 실행되지 않아요. 노드가 많아져 캔버스가 복잡하면 플로팅 패널의 **자동 정렬** 버튼을 누르세요. 노드 수에는 제한이 없어요. ## 노드 나누기 노드 하나가 여러 일을 한꺼번에 하거나, 에이전트가 지어낸 답을 하기 시작하면 노드를 나누세요. 노드마다 목적이 하나여야 고치고 테스트하기 쉬워요. 꽃배달 주문 변경을 예로 들면, 대화 노드가 주문자를 확인하면 추출 노드가 성함과 전화번호를 저장해요. 대화 노드가 주문 내역을 안내하고 바꿀 항목을 물으면, 추출 노드가 그 답을 변수로 저장하고 조건 노드가 상품명이나 배송일시를 다시 받는 노드로 보내요. 이처럼 대화, 추출, 조건 순서로 잇는 모양이 기본이에요. ## 관련 문서 노드마다 다음으로 넘어갈 조건을 정할 수 있어요. 어느 단계에서든 공통 상황을 한 노드에서 처리할 수 있어요. # 문자 발신 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/send-sms-node 예약 확인이나 상담 자료를 플로우의 정해진 지점에서 문자로 보내고, 결과에 맞춰 다음 안내를 정할 수 있어요. 문자 발신 노드는 플로우가 도착하면 통화 중인 고객에게 문자를 보내요. 고객의 답은 기다리지 않고, 발신 결과에 맞는 다음 노드로 넘어가요. 예약 확정 뒤 문자 발신 노드를 두고 요청 성공과 실패 안내로 연결한 플로우 발신번호의 문자 발신 승인이 있어야 이 노드를 쓸 수 있어요. 신청 방법은 [문자](/docs/operate/deploy/phone/sms)에 있어요. 에이전트가 보낼 때를 스스로 판단하게 하려면 [문자 발신 도구](/docs/build/tools/builtin/send-sms)를 쓰세요. ## 언제 사용하나요 * **예약을 확정한 뒤**: 예약 날짜와 시간을 문자로 남겨요. 예약 확정 노드 다음에 연결하세요. * **상담 자료를 안내한 뒤**: 고객이 열어 볼 자료 링크를 보내요. 자료 설명을 마친 지점에 두세요. * **통화를 마치기 직전**: 상담에서 정한 내용을 문자로 정리하고, 발신 결과를 안내한 뒤 통화를 끝내세요. ## 노드 설정하기 화면 아래에서 **문자 발신** 노드를 추가하고, `예약 확정을 안내한 경우` 같은 앞 노드의 전환 조건을 이 노드에 연결하세요. 발신 전에 할 말은 앞 [대화 노드](/docs/build/flow/nodes/conversation-node)에 적으세요. 추가와 연결 방법은 [노드 개요](/docs/build/flow/nodes/overview)에 있어요. 노드를 선택하고 **문자 내용**을 설정하세요. 새 노드는 **동적**이 기본값이고, 대화에서 확인한 예약 정보를 보내려면 `확정된 예약 날짜와 시간을 문자로 보내세요.` 같은 지침을 적어요. 정해 둔 문구를 보내려면 **정적**을 고르고 **본문**에 적으세요. 작성법, 변수, MMS 첨부는 [문자 발신 도구](/docs/build/tools/builtin/send-sms)에 있어요. **발신번호**도 고르세요. 기본값은 통화에 쓰는 번호예요. 문자 내용의 동적·정적 탭과 발신번호, 응답 대기 방식, 실행 중 대기음 설정 패널 결과마다 다르게 안내하려면 **응답 대기 방식**을 기본값인 **결과 기다리기**로 두세요. 결과를 기다릴 필요가 없으면 **요청만 보내고 계속 진행**을 고르세요. 기다리는 동안 들려줄 소리는 **실행 중 대기음**에서 골라요. 자세한 동작은 [실행 대기음](/docs/build/tools/tool-call-sound)에 있어요. **요청 성공 시**에는 다음 안내 노드를, **요청 실패 시**에는 실패를 안내할 노드를 연결하세요. 결과별로 나누려면 결과 기다리기를 쓰세요. ## 통화에서 일어나는 일 * **고객의 답을 기다리지 않아요.** 문자 발신 노드는 문자를 보내는 단계예요. 발신 안내와 고객에게 확인할 내용은 앞 대화 노드에서 먼저 처리하세요. * **결과 기다리기는 발신 요청의 응답을 기다려요.** 정상 응답이면 요청 성공 시로, 번호나 본문이 없거나 요청이 실패하면 요청 실패 시로 넘어가요. 성공이 고객 단말의 수신 완료를 뜻하지는 않아요. * **요청만 보내고 계속 진행은 결과를 기다리지 않아요.** 번호와 본문을 먼저 검사하고, 검사를 통과해 요청을 시작하면 성공 경로로 이어가요. 뒤늦게 발신이 실패해도 실패 경로로 돌아가지 않아요. ## 관련 문서 문자 작성법과 변수, MMS 첨부를 확인할 수 있어요. 발신번호의 문자 발신을 신청할 수 있어요. 노드를 추가하고 앞뒤 노드와 연결할 수 있어요. # 도구 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/tool-node 등록해 둔 API 도구를 플로우의 정해진 지점에서 실행하고, 결과에 맞춰 다음 안내로 이어갈 수 있어요. 도구 노드는 플로우가 도착하면 골라 둔 API 도구를 실행해요. 고객의 답은 기다리지 않고, 실행 결과에 맞는 다음 경로로 이어가요. 주문 조회 도구를 선택하고 배송 상태 안내와 조회 실패 안내로 연결한 플로우와 설정 패널 HTTP 요청을 노드 안에서 직접 설정하려면 [API 노드](/docs/build/flow/nodes/api-node)를 쓰세요. ## 언제 사용하나요 * **주문 번호를 확인한 뒤**: 등록한 주문 조회 도구를 실행하고, 다음 대화 노드에서 배송 상태를 안내해요. * **예약에 동의한 뒤**: 수집한 일시와 인원수로 접수 도구를 실행하고, 응답을 확인한 뒤 예약 결과를 안내해요. * **상담을 마친 뒤**: 상담 결과 저장 도구를 실행해요. 저장 결과가 필요 없다면 응답을 기다리지 않아도 돼요. ## 노드 설정하기 화면 아래에서 **도구** 노드를 추가하고, 앞 노드의 전환 조건을 이 노드에 연결하세요. 도구에 필요한 정보는 앞 단계에서 받아 두세요. 노드를 선택하고 **도구 선택**에서 도구를 고르세요. 워크스페이스의 커스텀 도구가 목록에 나오고, 고른 도구는 에이전트에도 자동으로 연결돼요. 원하는 도구가 없다면 [API 도구](/docs/build/tools/api)를 먼저 만드세요. 요청 주소, 인증, 입력값은 도구에서 설정해요. **프롬프트**에서 **정적**을 고르고 `주문 내역을 확인해 드릴게요.` 같은 안내를 적으세요. 상황에 맞춰 말하게 하려면 **동적**, 안내가 필요 없으면 **없음**을 고르세요. API 결과를 쓸 때는 도구의 **응답 대기 방식**이 **결과 기다리기**인지 확인하세요. 노드에서 들려줄 소리는 **실행 중 대기음**에서 골라요. **전환 조건**에 `주문 상태를 조회한 경우` 같은 정상 처리 조건을 추가하고, 결과를 안내할 다음 노드에 연결하세요. **요청 실패 시**에는 실패 안내 노드를 연결하세요. 응답 내용으로 나누려면 [전환 조건](/docs/build/flow/transitions)을 참고하고, 두 경로를 모두 테스트하세요. ## 통화에서 일어나는 일 노드에 도착하면 안내와 요청을 함께 시작해요. **결과 기다리기**에서는 안내와 응답이 모두 끝난 뒤 다음 경로를 판단하니, 이번 조회 결과는 다음 대화 노드에서 안내하세요. 도구 노드는 설정마다 따르는 값이 달라요. | 설정 | 도구 노드에서 따르는 값 | | - | - | | 실행 전 말하기 | 도구의 설정은 쓰지 않고, 노드의 프롬프트로 안내해요 | | 응답 대기 방식 | API 도구에 설정한 방식을 따라요. 노드에서는 바꾸지 않아요 | | 실행 중 대기음 | 노드에서 고른 값이 먼저예요. 고르지 않았으면 도구의 대기음을 따라요 | **요청만 보내고 계속 진행**은 응답을 기다리지 않아요. 노드의 안내가 끝나면 다음 경로를 판단하고, 응답 본문은 이후 대화에 쓰지 않아요. 뒤늦게 실패해도 실패 경로로 돌아가지 않아요. 자세한 설정은 [API 도구](/docs/build/tools/api#응답-대기-방식-고르기)와 [실행 대기음](/docs/build/tools/tool-call-sound)에 있어요. ## 문제가 생겼을 때 조회 결과가 필요하면 API 도구의 응답 대기 방식을 결과 기다리기로 바꾸세요. 요청만 보내고 계속 진행은 결과에 따른 분기에 쓸 수 없어요. 예약 불가를 처리할 일반 전환 조건을 추가하세요. 도구가 오류를 돌려줄 때만 요청 실패 시 경로로 가고, 정상 응답 안의 예약 불가는 응답 내용으로 나눠야 해요. 정상 경로의 전환 조건과 연결을 확인하세요. 일반 전환 조건이 없으면 정상 결과도 실패 경로로 이어질 수 있어요. 노드에서 다른 대기음을 고른 뒤 소리 없음으로 다시 바꾸세요. 아직 고르지 않은 노드도 소리 없음으로 보이고, 이때는 연결한 도구의 대기음을 따라요. ## 관련 문서 요청, 인증, 입력값과 응답 대기 방식을 설정할 수 있어요. 대기음 종류와 통화 중 재생 규칙을 확인할 수 있어요. 결과에 맞는 다음 경로를 쓸 수 있어요. 노드를 추가하고 앞뒤 노드와 연결할 수 있어요. # 에이전트 전환 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/transfer-agent-node 플로우가 정한 단계를 마친 고객을 원하는 지점에서 담당 에이전트에게 넘길 수 있어요. 에이전트 전환 노드는 플로우가 이 노드에 도착하면 통화를 같은 워크스페이스의 다른 에이전트에게 넘겨요. 언제 넘길지는 앞 노드의 전환 조건이 정하고, 에이전트가 판단하지 않아요. 플로우 편집기에서 에이전트 전환 노드를 선택하면 오른쪽에 에이전트 선택과 대화 컨텍스트 유지 설정이 보이는 화면 에이전트가 대화를 보고 스스로 넘기게 하려면 [에이전트 전환 도구](/docs/build/tools/builtin/transfer-agent)를 쓰세요. ## 언제 사용하나요 * **용건을 분류한 뒤 담당 에이전트에게 넘길 때**: 인사와 용건 분류를 마친 뒤 [조건 노드](/docs/build/flow/nodes/condition-node)로 나누고, 분기마다 담당 에이전트로 넘기는 노드를 둬요. * **플로우가 다루지 않는 문의가 나왔을 때**: 카드 분실 신고 플로우에서 다른 카드사 문의가 나오면 제휴 카드 상담 에이전트에게 넘겨요. * **정해진 절차를 마친 뒤 자유 상담으로 넘길 때**: 본인 확인처럼 순서가 정해진 단계는 플로우로 처리하고, 이후 상담은 프롬프트 에이전트에게 넘겨요. ## 노드 설정하기 화면 아래에서 **에이전트 전환** 노드를 추가하고, 앞 노드의 전환 조건을 이 노드에 연결하세요. 노드를 선택하고 **에이전트 선택**에서 에이전트와 버전을 고르세요. 운영 중인 플로우라면 **프로덕션**을 고르세요. **대화 컨텍스트 유지**를 켜면 지금까지의 대화를 대상 에이전트에게 넘겨요. 대상 에이전트는 앞선 대화를 이어받아 응대해요. 기본값은 꺼짐이에요. 노드의 **에러 발생 시** 전환 조건에 사과하고 다시 안내하는 대화 노드나 [통화 전환 노드](/docs/build/flow/nodes/transfer-node)를 연결하세요. 전환에 실패하면 플로우가 이 경로로 이어가요. ## 통화에서 일어나는 일 * **따로 안내하지 않고 바로 전환해요.** 노드에 도착하면 곧바로 대상 에이전트에게 넘겨요. * **대상 에이전트가 첫 메시지로 응대를 시작해요.** 대상 에이전트의 첫 메시지가 전환된 고객에게도 어울리는지 확인하세요. * **이후 응대는 대상 에이전트를 따라요.** 프롬프트, 목소리, 도구가 모두 대상 에이전트의 설정으로 바뀌어요. ## 관련 문서 에이전트가 대화를 보고 스스로 전환하게 할 수 있어요. 문의 유형별로 다른 전환 노드로 나눌 수 있어요. 버전을 배포하고 프로덕션으로 지정할 수 있어요. # 통화 전환 노드 Source: https://docs.tryvox.co/docs/build/flow/nodes/transfer-node 플로우가 정한 지점에서 통화를 상담사의 전화번호나 SIP 주소로 넘길 수 있어요. 통화 전환 노드는 플로우가 이 노드에 도착하면 전환 전 안내를 말하고 통화를 상담사의 전화번호나 SIP 주소로 넘겨요. 언제 넘길지는 앞 노드의 전환 조건이 정하고, 에이전트가 판단하지 않아요. 플로우 편집기에서 통화 전환 노드를 선택하면 오른쪽에 전환 대상, 전환 타입, 발신표기번호 설정이 보이는 화면 통화 전환 노드는 전화 통화에서만 동작해요. 에이전트가 대화를 보고 스스로 넘기게 하려면 [통화 전환 도구](/docs/build/tools/builtin/transfer-call)를 쓰세요. ## 언제 사용하나요 * **정해진 절차를 마친 뒤 상담사에게 넘길 때**: 본인 확인이나 접수 항목 수집을 플로우로 끝낸 뒤 상담사 번호로 넘겨요. * **문의 유형마다 받을 팀이 다를 때**: [조건 노드](/docs/build/flow/nodes/condition-node)로 항공, 투어, 숙소 문의를 나누고 분기마다 통화 전환 노드를 하나씩 둬요. * **어느 단계에서든 상담사 연결 요청을 받을 때**: [글로벌 노드](/docs/build/flow/advanced/global-node)를 켠 대화 노드에서 이 노드로 넘겨요. ## 노드 설정하기 화면 아래에서 **통화 전환** 노드를 추가하고, 앞 노드의 전환 조건을 이 노드에 연결하세요. 노드 위쪽 프롬프트에서 전환 직전에 고객에게 할 말을 고르세요. **동적**은 프롬프트를 바탕으로 상황에 맞는 문장을 만들어 말하고, **정적**은 적어 둔 문장을 그대로 말해요. **없음**을 고르면 아무 말 없이 전환해요. 고객이 통화가 끊겼다고 느끼지 않도록 "담당 상담사에게 연결해 드리겠습니다. 잠시만 기다려 주세요." 같은 안내를 넣어 두세요. **전환 대상**에서 **전화**나 **SIP**를 고르고 번호나 SIP URI를 넣으세요. 노드 하나에는 대상을 하나만 넣어요. `{{변수명}}` 꼴의 [동적 변수](/docs/build/variables/dynamic-variables)로 통화 시점에 번호를 정할 수도 있어요. API로 플로우를 만들 때도 대상은 `transferConfiguration.transferTo` 하나예요. **전환 타입**에서 **즉시 전환**이나 **안내 후 전환**을 고르세요. 차이와 고르는 기준은 [통화 전환 도구](/docs/build/tools/builtin/transfer-call#전환-방식-고르기)에 있어요. **발신표기번호**에서는 상담사 전화기에 **vox 에이전트 번호**와 **사용자 번호** 가운데 무엇을 띄울지 고르세요. **안내 후 전환**이면 상담사에게 전할 **안내 메시지**를 동적 요약이나 고정 문장으로 적고, SIP 대상이면 PBX에 넘길 **SIP 헤더**를 넣을 수 있어요. 설정은 [통화 전환 도구](/docs/build/tools/builtin/transfer-call#통화-전환-도구-추가하기)와 같아요. ## 통화에서 일어나는 일 * **안내를 마친 뒤 전환해요.** 노드에 도착하면 전환 전 안내를 말하고 상담사에게 넘겨요. * **이후 동작은 전환 타입을 따라요.** 즉시 전환은 넘기는 즉시 에이전트가 빠지고, 안내 후 전환은 상담사가 받지 않으면 에이전트가 응대를 이어가요. * **통화 기록에 종료 사유가 남아요.** [연결 종료 사유](/docs/operate/monitor/disconnection-reasons)는 `call_transfer`예요. ## 문제가 생겼을 때 실제 전화로 걸어 전환을 확인하세요. 대시보드는 저장 전에 전화번호와 SIP URI 형식을 검사하지만, 변수가 들어간 값은 통화 시점에 채워지므로 검사하지 않아요. 노드 위쪽 프롬프트가 없음으로 되어 있는지 확인하고 동적이나 정적으로 바꿔 안내를 넣으세요. ## 관련 문서 즉시 전환과 안내 후 전환의 동작, 안내 메시지, SIP 헤더를 볼 수 있어요. 문의 유형별로 다른 전환 노드로 나눌 수 있어요. 어느 노드에서든 상담사 연결 요청을 받을 수 있어요. # 플로우 에이전트 개요 Source: https://docs.tryvox.co/docs/build/flow/overview 대화를 노드로 나누고 조건에 따라 다음 단계로 넘겨, 순서가 정해진 상담을 그대로 따르는 에이전트를 만들 수 있어요. 플로우 에이전트는 대화를 여러 노드로 나누고, 노드마다 할 일과 다음으로 넘어갈 조건을 정해요. 한 프롬프트에 모든 규칙을 담는 대신 단계를 나눠서, 정해 둔 순서와 분기를 통화마다 똑같이 따라요. 시작 노드와 대화 노드, 종료 노드를 연결한 플로우 편집기와 하단 노드 메뉴 대화가 자유롭고 순서가 중요하지 않다면 [프롬프트 에이전트](/docs/build/single-prompt/overview)로 더 빨리 만들 수 있어요. ## 언제 사용하나요 * **순서를 지켜야 하는 상담**: 본인 확인을 마친 뒤에만 업무를 처리하는 것처럼 단계를 건너뛰면 안 될 때 써요. * **받을 정보가 정해진 접수**: 예약이나 주문 변경처럼 항목을 빠짐없이 받고, 빠진 것만 다시 물어요. * **결과에 따라 안내가 갈리는 통화**: API 조회나 고객의 답에 따라 다른 안내와 담당자로 나눠요. * **길고 복잡한 통화**: 단계마다 프롬프트가 짧아져서 고치고 테스트하기 쉬워요. ## 플로우 에이전트 만들기 **구축 > 에이전트**에서 에이전트를 만들 때 유형으로 **플로우**를 고르고, **템플릿**이나 **빈 에이전트**로 시작하세요. 편집기에서 바꾼 내용은 자동으로 저장돼요. 오른쪽 패널의 **테스트** 탭에서 통화해 보고, 원하는 대로 움직이면 버전을 배포해 운영에 쓰세요. 배포 방법은 [버전 관리](/docs/build/versioning)에 있어요. ## 대화 단계 설계하기 노드를 추가하고 전환 조건으로 이어 대화 순서를 만드세요. 노드 종류와 잇는 방법은 [노드 개요](/docs/build/flow/nodes/overview), 조건 쓰는 법은 [전환 조건](/docs/build/flow/transitions)에 있어요. 거절이나 상담사 연결 요청처럼 어느 단계에서나 나오는 상황은 [글로벌 노드](/docs/build/flow/advanced/global-node)로 한 번에 처리하세요.