> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.claw-ops.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.claw-ops.com/_mcp/server.

# 전화번호

> 국내 번호를 발급하고 착신 라우팅을 에이전트, 콜 플로우, Webhook, 전환, SIP로 연결합니다. 발신번호 사용과 반납까지 안내합니다.

전화번호는 ClawOps의 통화와 문자가 드나드는 창구입니다. 하나의 번호로 전화를 받고, 전화를 걸고, 문자를 보냅니다. 번호를 발급한 뒤 **착신 라우팅**을 지정하면 그 번호로 걸려온 전화를 누가 받을지 정해집니다.

번호는 ClawOps 번호 풀에서 자동으로 배정됩니다. 국가, 지역번호, 뒷자리를 지정할 수 없고 발급 전에 후보를 미리 볼 수도 없습니다. 어떤 번호가 나올지는 발급 응답에서 확인합니다.

## 번호 객체

발급, 조회, 수정 응답이 모두 같은 형태입니다.

| 필드                     | 타입             | 설명                                                                                |
| ---------------------- | -------------- | --------------------------------------------------------------------------------- |
| `number`               | string         | 전화번호입니다. 이 값이 곧 식별자이며 별도의 id는 없습니다.                                               |
| `numberType`           | string         | `did`(일반 번호) 또는 `representative`(대표번호)입니다.                                        |
| `source`               | string         | 번호 출처입니다. 풀에서 발급한 번호는 `pool`입니다.                                                  |
| `routingType`          | string         | 착신 라우팅입니다. `webhook`, `agent`, `callflow`, `forward`, `sip`, `softphone` 중 하나입니다. |
| `agentId`              | string \| null | `routingType`이 `agent`일 때 전화를 받을 에이전트입니다.                                         |
| `callFlowId`           | string \| null | `routingType`이 `callflow`일 때 전화를 받을 콜 플로우입니다.                                     |
| `forwardTo`            | string \| null | `routingType`이 `forward`일 때 전환할 대상 번호입니다.                                         |
| `sipEndpointId`        | string \| null | `routingType`이 `sip`일 때 다이얼할 SIP 엔드포인트입니다.                                        |
| `sipCredentialId`      | string \| null | `routingType`이 `softphone`일 때 착신할 등록 단말입니다.                                       |
| `webhookUrl`           | string \| null | `routingType`이 `webhook`일 때 호출할 VoiceML 주소입니다.                                    |
| `webhookMethod`        | string         | Webhook 호출 메서드입니다. `POST` 또는 `GET`이며 기본값은 `POST`입니다.                              |
| `webhookHeaders`       | object \| null | Webhook 호출에 덧붙일 HTTP 헤더입니다.                                                       |
| `callContextUrl`       | string \| null | `routingType`이 `agent`일 때 통화 시작 직전에 컨텍스트를 조회할 주소입니다.                              |
| `statusCallback`       | string \| null | 이 번호로 걸려온 통화의 상태를 통지할 주소입니다.                                                      |
| `statusCallbackEvents` | string \| null | 구독할 상태 이벤트입니다. 공백으로 구분합니다.                                                        |
| `dictionaryId`         | string \| null | 이 번호의 통화 전사에 적용할 받아쓰기 사전입니다.                                                      |
| `createdAt`            | string         | 발급 시각입니다.                                                                         |

라우팅에 쓰이지 않는 필드는 `null`로 내려옵니다. 예를 들어 `routingType`이 `agent`이면 `callFlowId`, `forwardTo`, `sipEndpointId`, `sipCredentialId`는 모두 `null`입니다.

## 번호 발급

```text
POST /v1/accounts/{accountId}/numbers
```

본문은 모두 선택이며 `{}`로 요청해도 발급됩니다. 여기서 지정한 값은 발급된 번호에 그대로 적용됩니다.

| 필드                     | 타입     | 설명                                                                |
| ---------------------- | ------ | ----------------------------------------------------------------- |
| `webhookUrl`           | string | 수신 전화를 처리할 VoiceML 주소입니다. 공개된 HTTP(S) 주소여야 합니다.                   |
| `webhookMethod`        | string | `POST` 또는 `GET`입니다. 기본값은 `POST`입니다.                               |
| `webhookHeaders`       | object | Webhook 호출에 덧붙일 헤더입니다. 아래 [Webhook 헤더 추가](#webhook-헤더-추가)를 참고하세요. |
| `statusCallback`       | string | 수신 통화의 상태를 통지받을 주소입니다.                                            |
| `statusCallbackEvents` | string | 구독할 상태 이벤트입니다. 생략하면 기본 집합이 적용됩니다.                                 |

```bash title="cURL"
curl -X POST "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

```python title="Python"
from clawops import ClawOps

client = ClawOps(
    api_key="YOUR_API_KEY",
    account_id="YOUR_ACCOUNT_ID",
)

number = client.numbers.create()

print(number.number, number.routing_type)
```

```typescript title="TypeScript"
import ClawOps from "@teamlearners/clawops";

const client = new ClawOps({
  apiKey: process.env.CLAWOPS_API_KEY,
  accountId: process.env.CLAWOPS_ACCOUNT_ID,
});

const number = await client.numbers.create();

console.log(number.number, number.routingType);
```

```json title="응답 (201)"
{
  "number": "07012341234",
  "numberType": "did",
  "source": "pool",
  "routingType": "webhook",
  "agentId": null,
  "callFlowId": null,
  "forwardTo": null,
  "sipEndpointId": null,
  "sipCredentialId": null,
  "webhookUrl": null,
  "webhookMethod": "POST",
  "webhookHeaders": null,
  "callContextUrl": null,
  "statusCallback": null,
  "statusCallbackEvents": null,
  "dictionaryId": null,
  "createdAt": "2026-08-13T04:12:44.123Z"
}
```

**발급만으로는 전화를 받지 못합니다.** 발급 직후 번호는 `routingType`이 `webhook`이고 `webhookUrl`이 비어 있어, 이 상태로 걸려온 전화는 거절됩니다. 이어서 [착신 라우팅](#착신-라우팅)을 지정하세요.

### 발급 조건

세 가지를 모두 만족해야 발급됩니다.

| 조건                                                      | 실패 시  |
| ------------------------------------------------------- | ----- |
| 계정에 활성 구독이 있어야 합니다.                                     | `403` |
| 요금제의 회선 수 한도 안이어야 합니다. 한도를 넘겨 발급하려면 회선 추가 부가서비스가 필요합니다. | `422` |
| 법인 계정은 법인 인증을 먼저 마쳐야 합니다.                               | `409` |

번호 풀이 비어 있으면 `503`이 반환됩니다. 이 경우 요청을 바꿔도 결과가 같으므로 잠시 후 다시 시도하세요.

## 번호 목록 조회

```text
GET /v1/accounts/{accountId}/numbers
```

```bash title="cURL"
curl "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```python title="Python"
numbers = client.numbers.list()

for n in numbers:
    print(n.number, n.routing_type)
```

```typescript title="TypeScript"
const numbers = await client.numbers.list();

for (const n of numbers) {
  console.log(n.number, n.routingType);
}
```

```json title="응답 (200)"
{
  "data": [
    {
      "number": "07012341234",
      "numberType": "did",
      "routingType": "agent",
      "agentId": "AG7c2f9b1e4a6d",
      "webhookUrl": null,
      "createdAt": "2026-08-13T04:12:44.123Z"
    }
  ]
}
```

## 착신 라우팅

`routingType`이 이 번호로 걸려온 전화를 누가 받을지 결정합니다.

| `routingType` | 전화를 받는 주체          | 필수 필드             | 전제 조건                                         |
| ------------- | ------------------ | ----------------- | --------------------------------------------- |
| `webhook`     | 내 서버가 응답하는 VoiceML | `webhookUrl`      | 기본값입니다. 주소가 없으면 전화가 거절됩니다.                    |
| `agent`       | 매니지드 에이전트          | `agentId`         | 같은 계정의 에이전트여야 합니다.                            |
| `callflow`    | 콜 플로우(ARS)         | `callFlowId`      | 같은 계정의 콜 플로우여야 합니다.                           |
| `forward`     | 계정이 보유한 다른 번호      | `forwardTo`       | 같은 계정이 보유한 번호만 지정할 수 있습니다.                    |
| `sip`         | 외부 PBX             | `sipEndpointId`   | SIP 트렁크 부가서비스, 활성 엔드포인트, 활성 라우트 1개 이상이 필요합니다. |
| `softphone`   | 등록된 소프트폰 단말        | `sipCredentialId` | SIP 트렁크 부가서비스와 활성 단말이 필요합니다.                  |

### 라우팅 변경

```text
PUT /v1/accounts/{accountId}/numbers/{number}
```

경로의 `{number}`는 번호 그 자체입니다(예: `07012341234`). 보낸 필드만 바뀌고 생략한 필드는 그대로 유지됩니다.

| 필드                     | 타입             | 설명                                            |
| ---------------------- | -------------- | --------------------------------------------- |
| `routingType`          | string         | 착신 라우팅입니다. 위 표의 여섯 값 중 하나입니다.                 |
| `agentId`              | string \| null | `routingType`이 `agent`일 때 필수입니다.              |
| `callFlowId`           | string \| null | `routingType`이 `callflow`일 때 필수입니다.           |
| `forwardTo`            | string \| null | `routingType`이 `forward`일 때 필수입니다.            |
| `sipEndpointId`        | string \| null | `routingType`이 `sip`일 때 필수입니다.                |
| `sipCredentialId`      | string \| null | `routingType`이 `softphone`일 때 필수입니다.          |
| `webhookUrl`           | string \| null | VoiceML 주소입니다.                                |
| `webhookMethod`        | string         | `POST` 또는 `GET`입니다.                           |
| `webhookHeaders`       | object \| null | Webhook 호출에 덧붙일 헤더입니다. `null`을 보내면 제거됩니다.     |
| `callContextUrl`       | string \| null | `routingType`이 `agent`일 때만 의미가 있습니다.          |
| `statusCallback`       | string \| null | 수신 통화 상태 통지 주소입니다. 빈 문자열이나 `null`을 보내면 해제됩니다. |
| `statusCallbackEvents` | string \| null | 구독할 상태 이벤트입니다.                                |
| `dictionaryId`         | string \| null | 받아쓰기 사전입니다. `null`을 보내면 계정 기본 사전으로 돌아갑니다.     |

**라우팅을 바꾸면 다른 라우팅 필드는 자동으로 비워집니다.** `agent`에서 `webhook`으로 되돌리면 `agentId`가 `null`이 되고, 다시 `agent`로 돌아갈 때 `agentId`를 새로 지정해야 합니다. 라우팅을 임시로 바꿨다가 되돌리는 운영을 한다면 원래 값을 직접 보관해 두세요.

### 에이전트가 받기

```bash title="cURL"
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routingType": "agent",
    "agentId": "AG7c2f9b1e4a6d"
  }'
```

```python title="Python"
number = client.numbers.update(
    "07012341234",
    routing_type="agent",
    agent_id="AG7c2f9b1e4a6d",
)
```

```typescript title="TypeScript"
const number = await client.numbers.update("07012341234", {
  routingType: "agent",
  agentId: "AG7c2f9b1e4a6d",
});
```

에이전트를 만드는 방법은 [에이전트](/agents)를 참고하세요. 번호에 연결된 에이전트는 삭제할 수 없으므로, 에이전트를 지우려면 먼저 번호의 라우팅을 다른 대상으로 바꿔야 합니다.

`callContextUrl`을 함께 지정하면 통화가 시작되기 직전에 그 주소를 호출해 통화별 지시문과 변수를 받아옵니다. 같은 에이전트로 걸려온 전화를 발신자에 따라 다르게 응대할 때 사용합니다. 조회에 실패하면 저장된 에이전트 설정만으로 통화를 계속합니다.

### 콜 플로우가 받기

```bash
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routingType": "callflow",
    "callFlowId": "CF41b8e07d9c25"
  }'
```

### 내 서버가 받기

```bash
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routingType": "webhook",
    "webhookUrl": "https://my-app.com/voice"
  }'
```

전화가 걸려오면 ClawOps가 이 주소를 호출하고, 응답으로 받은 VoiceML대로 통화를 진행합니다. 주소는 외부에서 접근할 수 있는 HTTP(S)여야 하며 내부망 주소는 거절됩니다.

### 보유한 다른 번호로 전환

```bash
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routingType": "forward",
    "forwardTo": "07012345678"
  }'
```

`forwardTo`는 **같은 계정이 보유한 번호**여야 합니다. 휴대폰이나 사무실 번호처럼 계정 밖의 번호로는 전환할 수 없고, 자기 자신으로도 전환할 수 없습니다. 외부 번호로 연결하려면 `callflow` 또는 `webhook` 라우팅에서 `<Dial>`을 사용하세요.

### SIP와 소프트폰

외부 PBX로 넘기거나(`sip`) 등록된 소프트폰 단말을 울리려면(`softphone`) SIP 트렁크 부가서비스가 활성화되어 있어야 합니다.

```bash
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routingType": "sip",
    "sipEndpointId": "SE9d3a5c71f2b8"
  }'
```

엔드포인트는 활성 상태여야 하고 활성 라우트가 하나 이상 있어야 합니다. 소프트폰은 활성화된 등록 단말이어야 하며, 세션용으로 발급한 임시 자격증명은 착신 대상이 될 수 없습니다.

## 수신 통화 상태 통지

`statusCallback`을 지정하면 이 번호로 **걸려온** 통화의 상태 전이를 그 주소로 통지합니다. 거는 통화의 상태는 통화를 생성할 때 지정하는 별도의 `statusCallback`으로 관리하며, 번호 설정은 관여하지 않습니다.

| 이벤트         | 통지 시점                                                            |
| ----------- | ---------------------------------------------------------------- |
| `initiated` | 통화가 시작됐습니다.                                                      |
| `ringing`   | 벨이 울리기 시작했습니다.                                                   |
| `answered`  | 통화가 연결됐습니다.                                                      |
| `completed` | 통화가 끝났습니다. 응답 없음, 통화 중, 거절, 실패도 이 토큰으로 통지되며 실제 사유는 페이로드에서 구분합니다. |
| `transfer`  | 호전환의 진행 상황입니다. **기본에 포함되지 않아** 받으려면 직접 나열해야 합니다.                 |

`statusCallbackEvents`를 생략하면 `initiated ringing answered completed`가 적용됩니다.

```bash
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "statusCallback": "https://my-app.com/call-status",
    "statusCallbackEvents": "initiated ringing answered completed transfer"
  }'
```

### Webhook 헤더 추가

`webhookHeaders`로 Webhook 호출에 헤더를 덧붙일 수 있습니다. 수신 측에서 요청의 출처를 구분할 때 사용합니다.

| 규칙         | 값                                           |
| ---------- | ------------------------------------------- |
| 키 접두사      | `X-`로 시작해야 합니다(대소문자 무관).                    |
| 사용할 수 없는 키 | `X-Signature`, `X-Forwarded-*`, `X-Real-IP` |
| 개수         | 최대 10개                                      |
| 키 길이       | 64 byte 이하                                  |
| 값 길이       | 2,048 byte 이하                               |
| 문자         | 출력 가능한 ASCII                                |

```json
{
  "webhookHeaders": {
    "X-Webhook-Token": "tenant-secret-abc123"
  }
}
```

`null`을 보내면 헤더가 제거되고, 필드를 아예 보내지 않으면 그대로 유지됩니다.

## 받아쓰기 사전 부착

`dictionaryId`를 지정하면 이 번호로 걸려온 통화의 전사에 해당 사전을 적용합니다. 상호명이나 제품명처럼 잘못 받아쓰기 쉬운 단어를 사전에 등록해 두면 정확도가 올라갑니다.

```bash
curl -X PUT "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dictionaryId": "DC6b41e8f0a92c"}'
```

부착한 사전은 계정 기본 사전을 **대체합니다.** 두 사전의 단어가 합쳐지지 않으므로, 기본 사전의 단어도 필요하다면 부착할 사전에 함께 넣어야 합니다. `null`을 보내면 부착이 해제되고 계정 기본 사전으로 돌아갑니다.

## 발신번호로 쓰기

전화를 걸거나 문자를 보낼 때 `From`에는 **계정이 보유한 번호**만 지정할 수 있습니다. 보유하지 않은 번호를 넣으면 `400`이 반환되며, 발신번호를 자동으로 골라 주는 동작은 없습니다.

```bash
curl -X POST "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/calls" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "To": "01012345678",
    "From": "07012341234"
  }'
```

문자 발송의 발신번호 규칙은 [문자 메시지](/messages)를 참고하세요.

## 대표번호

`15xx`, `18xx`로 시작하는 전국대표번호입니다. 일반 번호와 발급 경로와 제약이 다릅니다.

```text
POST /v1/accounts/{accountId}/representative-numbers
```

```bash
curl -X POST "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/representative-numbers" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

응답은 일반 번호와 같은 번호 객체이며 `numberType`이 `representative`입니다.

| 항목    | 내용                                                                                               |
| ----- | ------------------------------------------------------------------------------------------------ |
| 전제 조건 | 대표번호 부가서비스가 활성화되어 있어야 합니다. 비활성이면 `402`입니다.                                                       |
| 법인 계정 | 법인 인증을 마쳐야 합니다.                                                                                  |
| 라우팅   | **`forward`만 사용할 수 있습니다.** `webhook`, `agent`, `callflow`, `sip`, `softphone`으로 바꾸려 하면 `400`입니다. |
| 발급 직후 | `forwardTo`가 비어 있습니다. 전환 대상을 지정하기 전까지 걸려온 전화는 안내 멘트로 응답합니다.                                      |

대표번호는 전화를 직접 처리하지 않고 보유한 다른 번호로 넘기는 창구입니다. 에이전트가 대표번호를 받게 하려면 대표번호를 에이전트가 연결된 070 번호로 전환하세요.

## 관리번호 발급 링크

내 서비스의 이용자가 직접 방문해 번호를 발급받게 하려면 일회용 발급 링크를 만듭니다. 링크는 한 번만 사용할 수 있고, 사용되거나 만료되면 재사용할 수 없습니다. 관리번호 발급 부가서비스가 필요하며, 자세한 요청과 응답은 API 레퍼런스의 [발급 링크 생성](/api-reference/claw-ops-api/assignment-links/create-assignment-link)을 참고하세요.

## 번호 반납

```text
DELETE /v1/accounts/{accountId}/numbers/{number}
```

```bash
curl -X DELETE "https://api.claw-ops.com/v1/accounts/YOUR_ACCOUNT_ID/numbers/07012341234" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

성공하면 `204`가 반환되고 본문은 없습니다. 번호는 즉시 풀로 돌아가 다른 계정에 배정될 수 있습니다.

**반납은 되돌릴 수 없습니다.** 같은 번호를 다시 발급받는다는 보장이 없으므로, 안내물이나 광고에 노출된 번호는 반납 전에 대체 번호를 먼저 준비하세요.

반납해도 그 번호로 주고받은 통화와 문자 이력은 남아 계속 조회할 수 있습니다. 반납한 번호로 `forward` 하던 다른 번호가 있으면 그 번호는 함께 반납되지 않고 전환 대상만 해제됩니다.

## 오류

| 상태    | 상황                                                                                       |
| ----- | ---------------------------------------------------------------------------------------- |
| `400` | 필수 필드 누락, 잘못된 `routingType`, 대표번호에 `forward` 외 라우팅 지정, 지정한 에이전트·콜 플로우·엔드포인트·단말에 접근 권한 없음 |
| `402` | 대표번호 부가서비스가 비활성입니다.                                                                      |
| `403` | 번호 소유권이 없거나, 활성 구독이 없거나, SIP 트렁크 부가서비스가 비활성입니다.                                          |
| `404` | 계정에 그 번호가 없습니다.                                                                          |
| `409` | 법인 인증 미완료, 엔드포인트 비활성, 활성 라우트 없음, 단말 비활성                                                  |
| `422` | 요금제의 회선 수 한도를 초과했습니다.                                                                    |
| `503` | 발급 가능한 번호가 없거나 발급·반납 기능을 일시적으로 사용할 수 없습니다.                                               |

오류 응답에는 항상 `error`에 사람이 읽을 메시지가 담깁니다.

```json title="응답 (422)"
{
  "error": "Phone number quota exceeded (3/3)"
}
```

`code` 필드는 일부 오류에만 붙습니다. 라우팅 변경 실패는 `INVALID_AGENT`, `ENDPOINT_INACTIVE`처럼 코드가 함께 오지만, **발급 실패(한도 초과, 구독 없음, 풀 고갈)는 `error` 메시지만 옵니다.** 클라이언트에서 분기할 때는 `code`가 없을 수 있다는 전제로 HTTP 상태 코드를 기준으로 처리하세요.