> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryvox.co/llms.txt
> Use this file to discover all available pages before exploring further.

# 동적 변수

> 인바운드 웹훅, 단건/대량 발신, SDK, 테스트 프리셋 — 사용처에 맞춰 동적 변수를 주입하는 방법을 설명합니다.

# 동적 변수

동적 변수는 통화마다 값이 바뀌는 사용자 정의 변수입니다. 에이전트의 프롬프트·첫 메시지·키워드 강조·웹훅 URL 같은 영역에 `{{변수명}}` 형태로 자리 표시자를 두면, 통화가 시작될 때 주입된 값으로 치환됩니다. 덕분에 동일한 에이전트 하나로 수많은 고객 상황에 맞는 **개인화된 응대**를 할 수 있습니다.

<Info>
  **현재 시간(`current_time`), 발신·수신 번호(`call_from`, `call_to`), 통화 ID(`call_id`), 에이전트 ID(`agent_id`)** 는 플랫폼이 통화 시점에 자동으로 채워주는 시스템 변수입니다. 별도의 주입 설정이 필요 없으며, 프롬프트에서 바로 `{{변수명}}`으로 참조할 수 있습니다. 자세한 내용은 [시스템 변수](/docs/build/variables/system-variables) 문서를 확인하세요.

  이 문서는 **사용자 정의 동적 변수**를 주입하는 방법을 다룹니다.
</Info>

## 작성 문법

이중 중괄호 안에 영문·숫자·언더스코어로 된 변수명을 넣습니다. 변수명은 **대소문자를 구분**합니다.

```text theme={null}
안녕하세요 {{user_name}}님, 최근 구매하신 {{product_name}} 관련해서 연락드렸습니다.
```

* 공백은 허용됩니다: `{{ user_name }}` = `{{user_name}}`
* **치환은 프롬프트뿐 아니라 첫 메시지, 키워드 강조, API 도구의 웹훅 URL까지 동일하게 적용**됩니다.
* 값이 비어 있거나 전달되지 않은 변수는 통화 시작 경로에 따라 처리 방식이 달라질 수 있습니다. 변수가 비어 있을 때도 자연스러운 문장이 되도록 프롬프트에 분기를 둬서 작성하세요.

<Warning>
  **동적 변수 값은 문자열·숫자·불리언만 사용하세요.**

  배열·객체 같은 중첩 값도 저장은 가능하지만, LLM 프롬프트에 전달될 때 구조가 깨진 한 덩어리 문자열로 평탄화돼 안정적으로 다룰 수 없습니다.

  예를 들어 `{"address": {"city": "서울"}}` 같은 중첩 객체를 그대로 넘기면, LLM 은 따옴표·괄호가 섞인 문자열 한 덩어리로 받습니다.

  복잡한 구조를 넘겨야 한다면 호출 측에서 미리 `JSON.stringify` (또는 동등한 직렬화) 로 변환한 **문자열로** 전달하세요. 프롬프트에서도 LLM 에게 "JSON 문자열" 로 다루도록 명시해 주세요.
</Warning>

## 주입 경로 선택 가이드

"언제 값을 넣을 수 있는가"는 어떤 방식으로 통화를 시작하는지에 따라 달라집니다. 주입 경로는 다섯 가지입니다.

* **인바운드 통화** 는 통화 시작 직전 외부 서버에서 변수를 받아 옵니다. 분량이 많아 [인바운드 웹훅](/docs/build/variables/inbound-webhook) 페이지로 분리했습니다.
* **나머지 네 가지** — 아웃바운드 단건/대량 발신, SDK, 테스트 프리셋 — 은 아래에서 다룹니다.

<CardGroup cols={2}>
  <Card title="① 인바운드 통화 — 웹훅" icon="phone-arrow-down-left" href="/docs/build/variables/inbound-webhook">
    걸려온 번호를 보고 CRM에서 고객 정보를 조회해 주입합니다.
  </Card>

  <Card title="② 아웃바운드 단건 발신" icon="phone-arrow-up-right" href="#1-아웃바운드-단건-발신">
    대시보드 폼 또는 REST API로 한 통화씩 변수를 지정해 발신합니다.
  </Card>

  <Card title="③ 아웃바운드 대량 발신" icon="table" href="#2-아웃바운드-대량-발신">
    시트에 행을 채우고 컬럼을 그대로 변수로 전송합니다.
  </Card>

  <Card title="④ SDK" icon="code" href="#3-sdk">
    웹·모바일 SDK의 `dynamicVariables` 파라미터로 전달합니다.
  </Card>

  <Card title="⑤ 테스트 프리셋" icon="flask" href="#4-테스트-프리셋-웹-테스트-전용">
    대시보드에서 웹 테스트할 때만 사용하는 임시 프리셋입니다.
  </Card>
</CardGroup>

같은 변수를 여러 곳에서 받는다면, 각 경로는 **독립적**입니다. 에이전트는 해당 통화가 시작될 때 어느 경로로 왔는지에 따라 주입받은 값만 사용합니다.

***

## 1. 아웃바운드 단건 발신

한 번에 한 통씩, 통화 시작 시점에 변수 값을 지정해 발신하는 경로입니다. 대시보드 폼과 REST API 두 가지 방법이 제공됩니다.

<Tabs>
  <Tab title="대시보드">
    <img src="https://mintcdn.com/fleek/KJGN9YLDWG16egk5/images/screens/variables/dynamic-var-outbound-call.jpg?fit=max&auto=format&n=KJGN9YLDWG16egk5&q=85&s=49da25af7d5e7adf783fd51210159b03" alt="대시보드 단건 발신 페이지의 변수 설정 카드" style={{ borderRadius: "0.5rem" }} width="1920" height="1080" data-path="images/screens/variables/dynamic-var-outbound-call.jpg" />

    대시보드 **단건 발신** 페이지에서 에이전트를 선택하면 프롬프트에 포함된 `{{변수명}}`이 자동으로 추출되어 **변수 설정** 카드에 입력란이 렌더링됩니다. 각 변수 값을 채우고 **발신** 버튼을 누르면 통화가 즉시 시작됩니다.

    발신 번호·수신 번호·에이전트 선택 등 전체 흐름은 [단건 발신 가이드](/docs/operate/deploy/outbound-single)를 참고하세요.
  </Tab>

  <Tab title="REST API">
    `POST /v3/calls` 요청 본문의 `dynamic_variables` 객체에 이 통화에 주입할 키-값 쌍을 담습니다.

    ```bash cURL theme={null}
    curl --request POST \
      --url https://client-api.tryvox.co/v3/calls \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "from_number": "07011112222",
        "to_number": "01098765432",
        "agent": {
          "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
          "agent_version": "current"
        },
        "dynamic_variables": {
          "user_name": "김철수",
          "product_name": "보험상품A"
        }
      }'
    ```

    전체 파라미터·응답 구조·레이트 리밋은 [v3 API 레퍼런스](/api-reference/v3/introduction)를 확인하세요.
  </Tab>
</Tabs>

***

## 2. 아웃바운드 대량 발신

수십\~수만 건을 한 캠페인으로 발신할 때는 **시트**를 사용합니다. 시트의 각 컬럼이 그대로 동적 변수 이름이 되고, 행 하나당 통화 하나가 생성됩니다.

<Tabs>
  <Tab title="대시보드">
    <img src="https://mintcdn.com/fleek/KJGN9YLDWG16egk5/images/screens/variables/dynamic-var-batch-call.jpg?fit=max&auto=format&n=KJGN9YLDWG16egk5&q=85&s=be08b2aaa8b9aa1f479a96fe98b0e849" alt="대량 발신 시트 에디터의 전화번호 컬럼과 변수 컬럼" style={{ borderRadius: "0.5rem" }} width="1920" height="1080" data-path="images/screens/variables/dynamic-var-batch-call.jpg" />

    시트에서 `phone` 컬럼은 **수신 전화번호** 컬럼이고, 그 외에 직접 추가한 컬럼은 모두 해당 행 통화의 동적 변수로 주입됩니다. 컬럼명을 프롬프트의 `{{변수명}}`과 일치시키면 됩니다.

    ```
    | phone         | user_name | product_name | grade |
    | 01012345678   | 김철수     | 보험상품A     | vip   |
    | 01087654321   | 손예진     | 보험상품B     | vip   |
    ```

    첫 번째 행은 `{ user_name: "김철수", product_name: "보험상품A", grade: "vip" }` 로 주입되어 발신됩니다. 빈 셀이 있는 컬럼은 빈 값으로 전달될 수 있으므로, 필수 변수는 발신 전에 채우거나 프롬프트에서 값이 없을 때의 대응을 함께 정의하세요.

    시트 구성·캠페인 실행·스케줄링·재시도 정책 등 자세한 내용은 [대량 발신 가이드](/docs/operate/deploy/outbound-batch)를 참고하세요.
  </Tab>

  <Tab title="REST API">
    `POST /v3/campaigns` 요청 본문의 `tasks` 배열에 각 통화를 담아 보냅니다. 각 task의 `dynamic_variables`가 해당 통화에 주입됩니다.

    ```bash cURL theme={null}
    curl --request POST \
      --url https://client-api.tryvox.co/v3/campaigns \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "name": "신규 가입자 온보딩",
        "from_number": "07011112222",
        "agent": {
          "agent_id": "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
          "agent_version": "current"
        },
        "tasks": [
          {
            "call_to": "01098765432",
            "dynamic_variables": { "user_name": "김철수", "product_name": "보험상품A" }
          },
          {
            "call_to": "01076543210",
            "dynamic_variables": { "user_name": "손예진", "product_name": "보험상품B" }
          }
        ]
      }'
    ```

    전체 파라미터·동시성·재시도 옵션은 [v3 API 레퍼런스](/api-reference/v3/introduction)를 확인하세요.
  </Tab>
</Tabs>

***

## 3. SDK

JavaScript, React, React Native, Flutter SDK는 모두 통화 시작 메서드의 옵션으로 `dynamicVariables` 파라미터를 받습니다. 문자열·숫자·불리언 값을 키-값 쌍으로 전달하면 해당 통화에만 적용됩니다.

```ts theme={null}
await vox.startCall({
  agentId: "a1f4c8d2-3e5b-4a7c-9d8e-2b1f6c4a9d3e",
  dynamicVariables: {
    userName: "김철수",
    productName: "보험상품A",
    isVip: true,
  },
});
```

프롬프트에서는 다음과 같이 참조합니다:

```text theme={null}
안녕하세요 {{userName}}님, 최근 {{productName}} 관련 문의가 있으셨죠?
```

SDK별 옵션과 타입 정의는 각 가이드를 참고하세요.

* [JavaScript SDK](/docs/sdk/javascript)
* [React SDK](/docs/sdk/react)
* [React Native SDK](/docs/sdk/react-native)
* [Flutter SDK](/docs/sdk/flutter)

***

## 4. 테스트 프리셋 (웹 테스트 전용)

에이전트 빌드 화면의 테스트 영역에는 **테스트 프리셋** 시트가 있습니다. 여기서 설정한 동적 변수는 **대시보드 웹 테스트 통화에서만** 사용됩니다 — 실제 인바운드/아웃바운드 통화에는 전혀 반영되지 않으니 주의하세요.

<img src="https://mintcdn.com/fleek/KJGN9YLDWG16egk5/images/screens/variables/dynamic-var-test-preset.jpg?fit=max&auto=format&n=KJGN9YLDWG16egk5&q=85&s=b3e4a12e74a8c2c7f74619f238af71f4" alt="에이전트 빌드 화면의 테스트 프리셋 시트" style={{ borderRadius: "0.5rem" }} width="1920" height="1080" data-path="images/screens/variables/dynamic-var-test-preset.jpg" />

* 시트 제목: **테스트 프리셋**
* 설명: *"동적 변수를 설정합니다."*
* 저장 버튼: **저장**

값은 키-값 쌍으로 자유롭게 입력할 수 있으며, 웹 테스트 세션이 시작될 때 해당 값이 프롬프트에 주입됩니다. 대화 흐름을 빠르게 시뮬레이션해 볼 때 유용합니다.

<Warning>
  테스트 프리셋은 **실제 통화 동작을 대체하지 않습니다**. 배포 전에는 반드시 실제 경로(인바운드 웹훅 / 단건·대량 발신 / SDK)로도 검증하세요.
</Warning>

***

## 예외 상황 정리

| 상황                        | 동작                     |
| ------------------------- | ---------------------- |
| 프롬프트 에이전트에서 값이 전달되지 않은 변수 | `{{변수명}}`이 그대로 남을 수 있음 |
| 플로우 에이전트에서 값이 없는 변수       | 빈 문자열로 치환될 수 있음        |
| 대시보드 단건 발신에서 빈 입력         | 빈 문자열로 전달될 수 있음        |
| 시스템 변수와 이름 충돌             | 시스템 변수가 사용자 정의 값을 덮어씀  |

<Tip>
  필수 변수는 호출 전에 검증하세요. 값이 없을 수 있다면 "고객 이름이 없으면 먼저 이름을 확인한다"처럼 프롬프트에 대체 흐름을 넣어두는 것이 안전합니다.
</Tip>

인바운드 웹훅의 타임아웃·실패·SIP 헤더 충돌 동작은 [인바운드 웹훅 예외 상황](/docs/build/variables/inbound-webhook#예외-상황) 에서 다룹니다.

## 관련 문서

* [인바운드 웹훅](/docs/build/variables/inbound-webhook) — 통화 시작 직전 외부 서버에서 동적 변수 받기
* [시스템 변수](/docs/build/variables/system-variables)
* [SIP 트렁킹](/docs/operate/deploy/sip-telephony) — SIP 헤더 기반 주입
* [단건 발신](/docs/operate/deploy/outbound-single)
* [대량 발신](/docs/operate/deploy/outbound-batch)
* [JavaScript SDK](/docs/sdk/javascript) · [React SDK](/docs/sdk/react) · [React Native SDK](/docs/sdk/react-native) · [Flutter SDK](/docs/sdk/flutter)
* [통화 데이터 웹훅](/docs/build/security/webhooks)

***

<Accordion title="연관 검색어">
  동적 변수, dynamic variables, 변수 주입, 변수 치환, 단건 발신, 대량 발신, outbound call, SDK 변수, 테스트 프리셋, 개인화, 사용자 정의 변수, nested 값, 중첩 객체, JSON 직렬화, CRM 연동
</Accordion>
