# 번호 설정 수정 (/docs/api/numbers/updateNumber)
**PUT /v1/accounts/{accountId}/numbers/{number}**
```json
{
  "operationId": "updateNumber",
  "summary": "번호 설정 수정",
  "description": "등록된 번호의 설정을 수정합니다. webhookUrl/webhookMethod 외에 routingType/sipEndpointId/sipCredentialId 도 수정 가능합니다. routingType=sip 으로 변경 시 sip_trunk 애드온이 활성화돼 있어야 하며, sipEndpointId 는 같은 계정 소유의 active 엔드포인트(활성 라우트 1개 이상)여야 합니다. routingType=softphone 으로 변경 시에도 sip_trunk 애드온이 필요하며, sipCredentialId 는 같은 계정 소유의 active·enabled SIP credential(등록 단말)이어야 합니다.",
  "tags": [
    "Numbers"
  ],
  "parameters": [
    {
      "name": "accountId",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string"
      },
      "description": "계정 ID",
      "example": "AC1a2b3c4d"
    },
    {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string"
      },
      "description": "수정할 전화번호",
      "example": "1001"
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "webhookUrl": {
              "type": "string",
              "nullable": true,
              "example": "https://my-app.com/voice",
              "description": "routingType='webhook'에서 수신 전화를 처리할 VoiceML Webhook URL"
            },
            "callContextUrl": {
              "type": "string",
              "nullable": true,
              "example": "https://api.example.com/integrations/clawops/call-context",
              "description": "routingType='agent'에서 Managed Agent 시작 직전에 통화별 CallContext를 조회할 동기 endpoint. 응답은 {\"CallContext\":{\"Instruction\":\"...\",\"Variables\":{...}}} 형식이며, 조회 실패 시 저장된 Agent 설정만으로 통화를 계속합니다."
            },
            "webhookMethod": {
              "type": "string",
              "enum": [
                "POST",
                "GET"
              ],
              "description": "Webhook 호출 HTTP 메서드"
            },
            "routingType": {
              "type": "string",
              "enum": [
                "webhook",
                "sip",
                "softphone",
                "forward",
                "agent",
                "callflow"
              ],
              "description": "Agent 미연결/거부 시 fallback 라우팅. 'sip' 로 변경 시 sip_trunk 애드온 + 유효한 sipEndpointId 필요. 'softphone' 으로 변경 시 sip_trunk 애드온 + 유효한 sipCredentialId(등록 단말) 필요. 'forward' 로 변경 시 forwardTo(같은 계정 보유 번호) 필요 — 내부 착신전환. 'agent' 로 변경 시 agentId 필요 — 매니지드 에이전트가 전화를 받습니다. 'callflow' 로 변경 시 callFlowId 필요 — 이 번호로 걸려온 전화를 콜 플로우(결정적 ARS)가 받습니다. 'webhook' 으로 되돌리면 다른 라우팅 ID가 자동으로 null 처리됩니다."
            },
            "sipEndpointId": {
              "type": "string",
              "nullable": true,
              "description": "routingType='sip' 일 때 라우팅할 SipEndpoint id. 같은 계정 소유 + status=active + 활성 라우트 1개 이상이어야 함."
            },
            "sipCredentialId": {
              "type": "string",
              "nullable": true,
              "description": "routingType='softphone' 일 때 착신할 등록 SIP credential(단말) id. 같은 계정 소유 + status=active + enabled 여야 하며, ephemeral(세션) credential 은 사용 불가."
            },
            "forwardTo": {
              "type": "string",
              "nullable": true,
              "description": "routingType='forward' 일 때 내부 착신전환할 대상 번호(같은 계정 보유 번호). 한국 번호 정규화 후 저장. 주면 전환 대상이 이 번호 하나가 됩니다."
            },
            "forwardTargets": {
              "type": "array",
              "nullable": true,
              "maxItems": 10,
              "items": {
                "type": "string"
              },
              "description": "routingType='forward' 일 때 전환 대상 목록(최대 10개). 모두 동시에 울리고 먼저 받은 쪽으로 연결됩니다. 둘 이상이면 모든 대상이 SIP 단말(routingType='softphone')로 받는 같은 계정 번호여야 합니다. forwardTo 와 함께 줄 수 없습니다."
            },
            "callFlowId": {
              "type": "string",
              "nullable": true,
              "description": "routingType='callflow' 일 때 인입을 처리할 콜 플로우 id. 같은 계정 소유여야 합니다. id 는 `GET /v1/accounts/{accountId}/call-flows` 로 조회합니다."
            },
            "agentId": {
              "type": "string",
              "nullable": true,
              "description": "routingType='agent' 일 때 인입을 처리할 매니지드 에이전트 id. 같은 계정 소유여야 합니다. id 는 `GET /v1/accounts/{accountId}/agents` 로 조회합니다."
            },
            "webhookHeaders": {
              "type": "object",
              "nullable": true,
              "additionalProperties": {
                "type": "string"
              },
              "description": "Inbound webhook 호출 시 추가될 HTTP 헤더. 같은 통화의 후속 요청(action·<Redirect>·referUrl)\n중 webhookUrl 과 origin(scheme·host·port)이 같은 요청에도 실립니다. 상태 콜백에는 실리지 않습니다.\n키는 \"X-\" prefix 필수\n(case-insensitive), reserved 헤더(X-Signature, X-Forwarded-*, X-Real-IP) 거절.\n최대 10 entries, key ≤ 64 bytes, value ≤ 2048 bytes, ASCII printable.\nnull 전송 시 헤더 제거, 미포함 시 변경 없음.\n",
              "example": {
                "X-Webhook-Token": "tenant-secret-abc123"
              }
            },
            "statusCallback": {
              "type": "string",
              "nullable": true,
              "example": "https://my-app.com/call-status",
              "description": "수신(inbound) 통화 상태 webhook URL. 빈 문자열/null 전송 시 해제."
            },
            "statusCallbackEvents": {
              "type": "string",
              "nullable": true,
              "example": "initiated ringing answered completed transfer",
              "description": "구독할 상태 이벤트(공백 구분, 선택). 미지정 시 `initiated ringing answered completed` 가 적용됩니다. `transfer`(호전환 진행 상황)는 기본에 포함되지 않으므로 받으려면 직접 나열하세요. 전체 목록은 [Webhooks](/webhooks).\n"
            },
            "dictionaryId": {
              "type": "string",
              "nullable": true,
              "description": "받아쓰기 사전 부착. 같은 계정 소유 사전 id 를 지정하면 이 번호로 걸려온 통화 전사에 해당 사전을 대체 적용(병합 아님). null 전송 시 부착 해제(계정 기본 사전 폴백). 미포함 시 변경 없음."
            },
            "friendlyName": {
              "type": "string",
              "nullable": true,
              "example": "고객센터 대표",
              "description": "번호 별칭(용도 메모). 앞뒤 공백은 지워 저장하며 최대 50자, 줄바꿈 등 제어문자는 쓸 수 없습니다. null 또는 빈 문자열을 보내면 별칭을 지웁니다. 미포함 시 변경 없음. 라우팅에는 영향이 없습니다."
            },
            "rejectCallerIdRestricted": {
              "type": "boolean",
              "example": true,
              "description": "true 면 이 번호로 걸려 오는 번호 표시제한 수신 통화를 받지 않고 거절합니다. 거절된 통화는 통화 기록에 `status=rejected`, `hangupCause=caller_id_restricted_rejected` 로 남습니다. routingType 과 무관하게 적용되며 미포함 시 변경 없음. 통신사가 표시제한 여부를 보내지 않는 경로에서는 거절되지 않을 수 있습니다. 특정 번호의 수신 통화를 막으려면 수신 통화 차단(`POST /v1/accounts/{accountId}/blocked-callers`)을 사용하세요."
            }
          }
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "수정 성공",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "number": {
                "type": "string",
                "example": "07012340001",
                "description": "전화번호"
              },
              "source": {
                "type": "string",
                "example": "pool",
                "description": "번호 출처 (pool 등)"
              },
              "webhookUrl": {
                "type": "string",
                "nullable": true,
                "example": "https://my-app.com/voice"
              },
              "webhookMethod": {
                "type": "string",
                "enum": [
                  "POST",
                  "GET"
                ],
                "example": "POST"
              },
              "callContextUrl": {
                "type": "string",
                "nullable": true,
                "example": "https://api.example.com/integrations/clawops/call-context",
                "description": "routingType='agent'에서 Managed Agent 시작 전에 통화별 CallContext를 조회하는 동기 endpoint."
              },
              "routingType": {
                "type": "string",
                "enum": [
                  "webhook",
                  "sip",
                  "softphone",
                  "forward",
                  "callflow",
                  "agent"
                ],
                "example": "webhook",
                "description": "Agent 미연결/거부 시 fallback 라우팅. 'webhook' = webhookUrl 호출, 'sip' = sipEndpointId 의 OriginationRoute 로 외부 PBX 다이얼, 'softphone' = sipCredentialId 의 등록 단말로 착신(Kamailio usrloc fork), 'forward' = forwardTo(보유 번호)로 내부 착신전환, 'callflow' = callFlowId 의 콜 플로우(결정적 ARS)가 인입을 받음, 'agent' = agentId 의 매니지드 에이전트가 받음."
              },
              "sipEndpointId": {
                "type": "string",
                "nullable": true,
                "example": null,
                "description": "routingType='sip' 일 때 사용할 SipEndpoint id. 그 외 라우팅에서는 null."
              },
              "sipCredentialId": {
                "type": "string",
                "nullable": true,
                "example": null,
                "description": "routingType='softphone' 일 때 착신할 등록 SIP credential(단말) id. 그 외 라우팅에서는 null."
              },
              "forwardTo": {
                "type": "string",
                "nullable": true,
                "example": null,
                "description": "routingType='forward' 일 때 내부 착신전환 대상 번호(같은 계정 보유 번호). 대상이 여러 개면 첫 번째 대상. 그 외 라우팅에서는 null."
              },
              "forwardTargets": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": [],
                "description": "routingType='forward' 일 때 전환 대상 전체(첫 번째가 forwardTo). 모두 동시에 울리고 먼저 받은 쪽으로 연결됩니다. 미설정이거나 그 외 라우팅이면 빈 배열."
              },
              "callFlowId": {
                "type": "string",
                "nullable": true,
                "example": null,
                "description": "routingType='callflow' 일 때 인입을 처리할 콜 플로우 id. 그 외 라우팅에서는 null."
              },
              "agentId": {
                "type": "string",
                "nullable": true,
                "example": null,
                "description": "routingType='agent' 일 때 인입을 처리할 매니지드 에이전트 id. 그 외 라우팅에서는 null."
              },
              "webhookHeaders": {
                "type": "object",
                "nullable": true,
                "additionalProperties": {
                  "type": "string"
                },
                "description": "Inbound webhook 호출 시 추가될 HTTP 헤더. 같은 통화의 후속 요청(action·<Redirect>·referUrl)\n중 webhookUrl 과 origin(scheme·host·port)이 같은 요청에도 실립니다. 상태 콜백에는 실리지 않습니다.\n키는 \"X-\" prefix 필수\n(case-insensitive), reserved 헤더(X-Signature, X-Forwarded-*, X-Real-IP) 거절.\n최대 10 entries, key ≤ 64 bytes, value ≤ 2048 bytes, ASCII printable.\nnull 전송 시 헤더 제거, 미포함 시 변경 없음.\n",
                "example": {
                  "X-Webhook-Token": "tenant-secret-abc123"
                }
              },
              "statusCallback": {
                "type": "string",
                "nullable": true,
                "example": "https://my-app.com/call-status",
                "description": "수신(inbound) 통화 상태 webhook URL. 발신은 통화 생성 시 statusCallback 으로 별도 관리."
              },
              "statusCallbackEvents": {
                "type": "string",
                "nullable": true,
                "example": "initiated ringing answered completed transfer",
                "description": "구독할 상태 이벤트(공백 구분). 미지정 시 `initiated ringing answered completed` 가 적용됩니다. `transfer`(호전환 진행 상황)는 기본에 포함되지 않으므로 받으려면 직접 나열하세요.\n"
              },
              "numberType": {
                "type": "string",
                "enum": [
                  "did",
                  "representative"
                ],
                "example": "did",
                "description": "번호 유형. did = 일반 번호, representative = 대표번호."
              },
              "dictionaryId": {
                "type": "string",
                "nullable": true,
                "example": null,
                "description": "부착된 받아쓰기 사전 id. null 이면 이 번호로 걸려온 통화 전사에 계정 기본 사전을 사용."
              },
              "friendlyName": {
                "type": "string",
                "nullable": true,
                "maxLength": 50,
                "example": "고객센터 대표",
                "description": "번호마다 적어 두는 용도 메모(별칭). null 이면 별칭 없음. 발신 표시·라우팅에는 쓰이지 않습니다."
              },
              "rejectCallerIdRestricted": {
                "type": "boolean",
                "example": false,
                "description": "번호 표시제한 수신 통화를 받지 않고 거절하는지 여부. 기본 false."
              },
              "createdAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        }
      }
    },
    "400": {
      "description": "잘못된 요청 — 수정할 필드 없음 / webhookMethod 부적합 / routingType 부적합 / routingType=sip 인데 sipEndpointId 없음 / 엔드포인트 소유권 없음 / routingType=softphone 인데 sipCredentialId 없음 / credential 소유권 없음 / 별칭이 50자 초과이거나 제어문자 포함 / rejectCallerIdRestricted 가 불리언이 아님(VALIDATION, INVALID_ENDPOINT, INVALID_CREDENTIAL, invalid_friendly_name)",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "401": {
      "description": "인증 실패",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "403": {
      "description": "번호 소유권 없음 또는 sip_trunk 애드온 비활성(FEATURE_DISABLED)",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "404": {
      "description": "번호를 찾을 수 없음",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "409": {
      "description": "엔드포인트 비활성(ENDPOINT_INACTIVE) / 활성 라우트 없음(NO_ACTIVE_ROUTES) / SIP 단말 비활성(CREDENTIAL_INACTIVE)",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}
```