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

# 전화번호 인증 API: SMS 일회용 코드 발송

> Didit의 POST /v3/phone/send/로 SMS 일회용 코드를 발송합니다. 차단된 번호는 자동 재시도, 유효 시간 5-min, 사용량 기반 과금, 월 최소 약정 없음.

## SMS에 브랜드 이름 표시하기

SMS 코드에는 Business Console에서 설정한 애플리케이션의 SMS 발신자 이름이 추가 요금 없이 포함됩니다:

> 123456은 **Acme Bank**의 인증 코드입니다

코드 하나에 다른 이름을 표시하려면 `options.sms_sender_name`을 전달하십시오. 이 값은 1자 이상 30자 이하이어야 하며, 문자, 숫자, 공백, ' & - ! 만 사용할 수 있고 숫자만으로 구성할 수는 없습니다:

```json theme={null}
{
  "phone_number": "+14155552671",
  "options": {
    "preferred_channel": "sms",
    "sms_sender_name": "Acme Bank"
  }
}
```

이 규칙을 벗어난 이름은 `400` 응답을 반환하며, 코드는 전송되지 않습니다.
WhatsApp 코드는 고정된 메시지를 사용하므로 브랜드가 적용되지 않습니다. 비즈니스 이름으로 WhatsApp 코드를 전송하려면 Business Console에서 자체 WhatsApp Business 번호를 연결하십시오. 자세한 내용은 [자체 번호로 WhatsApp 코드 보내기](https://docs.didit.me/ko/core-technology/phone-verification/overview.md#자체-번호로-whatsapp-코드-발송)를 참조하십시오.
코드에 적용되는 이름과 새 이름의 일일 한도는 [브랜드가 적용된 인증 메시지](https://docs.didit.me/ko/core-technology/phone-verification/overview.md#브랜드-맞춤형-인증-메시지)를 참조하십시오.

## 제공업체 장애 처리하기

전화 제공업체를 일시적으로 사용할 수 없으면 이 endpoint는 `502`와 안정적인 기계 판독용 코드를 반환합니다:

```json theme={null}
{
  "detail": "The phone verification provider is temporarily unavailable.",
  "code": "phone_provider_unavailable"
}
```

이 응답은 재시도 가능한 것으로 처리하십시오. 짧은 백오프를 적용한 후 재시도하고, 사용자에게 유효한 전화번호나 코드를 변경하도록 요구하는 대신 일시적인 서비스 장애 메시지를 표시하십시오.


## OpenAPI

````yaml ko/openapi-25.json POST /v3/phone/send/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: 신분증 인증 API입니다. x-api-key 헤더로 인증합니다.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/phone/send/:
    post:
      tags:
        - Standalone APIs
      summary: 전화번호 코드 전송
      description: >-
        WhatsApp, SMS 또는 기타 지원되는 채널을 통해 전화번호로 일회용 비밀번호(OTP)를 전송한 후, [`POST
        /v3/phone/check/`](/ko/standalone-apis/phone-check)를 호출하여 이를 검증합니다.


        **전송 및 확인 작동 방식.** 인증 상태는 애플리케이션과 E.164 형식의 `phone_number`를 키로 식별됩니다. 확인
        호출에는 `request_id`가 사용되지 않습니다. 새로 전송할 때마다 **5분** 동안 유효한 대기 중인 인증이 생성됩니다.
        유효 시간이 만료되기 전에 동일한 번호와 사용자가 수신한 코드로 확인 호출을 실행하세요. 인증이 대기 중인 상태에서 동일한 번호로
        전송을 다시 호출하면 해당 인증에 대한 코드가 재전송됩니다(`status: "Retry"`, 동일한 `request_id`).
        이러한 재시도는 최대 1회까지 연결되며(총 2회 전송), 추가로 전송하면 새 `request_id`로 새로운 인증이 시작됩니다.
        5분의 유효 시간은 최초 전송 시점부터 측정되며 재시도로 인해 연장되지 않습니다.


        **전송 채널.** `options.preferred_channel`로 채널을 선택합니다(기본값은 `whatsapp`이며,
        `sms`, `telegram`, `voice`, `rcs`, `viber`, `zalo`도 지원됨). 수신 국가 또는 번호에서
        기본 설정 채널을 사용할 수 없는 경우 전송은 자동으로 SMS로 대체됩니다. 이때 전송은 여전히 `Success`를 반환하며,
        실제로 사용된 채널은 확인 응답(`phone.verification_method` 및 `lifecycle` 이벤트)에 보고됩니다.


        **브랜딩.** SMS 코드는 추가 비용 없이 Business Console에서 설정한 애플리케이션의 SMS 발신자 이름을
        사용합니다. 특정 코드에 다른 발신자 이름을 표시하려면 `options.sms_sender_name`을 전달하거나, 발신자 이름이
        설정되지 않았을 때 화이트 라벨 공개 이름으로 대체하려면 `options.use_white_label_customization:
        true`를 전달하세요. WhatsApp 코드는 고정된 메시지를 사용합니다. Business Console에서 자체
        WhatsApp Business 번호를 연결하면 비즈니스 이름과 번호로 코드를 전송할 수 있으며, Didit 수수료만 청구됩니다.


        **전송 상태.** `Success` — 새 인증을 위해 OTP가 전송됨, `Retry` — 대기 중인 인증을 위해 OTP가
        재전송됨, `Blocked` — 부정행위 방지 계층에서 전송을 거부함(`reason` 참조. 예:
        `repeated_attempts`, `suspicious`, `spam`). `Blocked` 전송은 고위험 경고와 함께 인증을
        즉시 `Declined`로 완료하므로, 후속 확인 호출 시 `Expired or Not Found`가 반환됩니다.


        **결제.** 가격은 수신 국가와 메시지를 실제로 전송한 채널에 따라 달라집니다([전화번호 인증
        요금](/ko/getting-started/phone-verification-pricing) 참조). `Blocked` 전송만
        무료가 보장됩니다. 그 외 청구되지 않은 모든 전송 시도는 전송이 확인되지 않았거나 전송 제공업체에서 메시지 전송 불가로 보고한
        경우라도 인증 완료 또는 만료 시점에 요금이 부과됩니다. 확인 호출은 항상 무료입니다. 악용 방지 조치로, 조직의 첫 충전이
        완료될 때까지 전화번호 인증이 비활성화됩니다(`403`).


        **세션 지속성.** 모든 새 인증은 API 유형 세션으로 저장됩니다. `request_id`는 `GET
        /v3/session/{sessionId}/decision/`에 전달할 수 있는 실제 세션 ID이며, 해당 인증은 Business
        Console에 표시되고 진행 상황에 따라 `status.updated` webhook이 트리거됩니다.


        **샌드박스.** 샌드박스 API 키는 전송 및 결제를 건너뜁니다. 요청 검증(형식이 잘못된 입력은 여전히 `400` 반환) 후
        endpoint는 임의의 `request_id`가 포함된 정적 `Success` payload를 반환합니다. 메시지는 전송되지
        않으며 어떤 데이터도 저장되지 않습니다. 샌드박스 확인 시에는 코드 `123456`을 사용하세요.


        **인증.** `x-api-key` 헤더에 애플리케이션의 API 키를 전송하세요. 자격 증명이 누락되었거나 유효하지 않으면
        `403`(`{"detail": "You do not have permission to perform this
        action."}`)이 반환됩니다. 이 API는 `401`을 반환하지 않습니다.


        **속도 제한.** 모든 POST/PATCH/DELETE endpoint에 걸쳐 API 키당 분당 300회의 공유 쓰기 요청
        한도가 적용되며, 추가로 전화번호당 시간당 4회의 악용 방지 전송 한도가 적용됩니다. 둘 중 하나라도 초과하면 `429`가
        반환됩니다.
      operationId: post_v3phone_send
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  type: string
                  maxLength: 20
                  description: >-
                    E.164 형식의 수취인 전화번호입니다. 앞자리에 `+`와 국가 코드가 포함됩니다(예:
                    `+14155552671`). 번호는 검증 후 E.164 형식으로 정규화되며, 구문 분석할 수 없거나
                    유효하지 않은 번호는 `phone_number` 필드 오류와 함께 `400`을 반환합니다.
                  example: '+14155552671'
                options:
                  type: object
                  description: OTP 전송 옵션입니다. 모든 필드는 선택 사항입니다.
                  properties:
                    code_size:
                      type: integer
                      minimum: 4
                      maximum: 8
                      default: 6
                      description: OTP의 자릿수입니다.
                    locale:
                      type: string
                      maxLength: 5
                      pattern: ^[a-z]{2,3}(-[A-Z]{2,3})?$
                      description: >-
                        인증 메시지를 현지화하는 데 사용되는 BCP-47 로캘입니다(예: `en-US`, `fr`,
                        `es`). 잘못된 형식은 `400`을 반환합니다.
                      example: en-US
                    preferred_channel:
                      type: string
                      enum:
                        - whatsapp
                        - sms
                        - telegram
                        - voice
                        - rcs
                        - viber
                        - zalo
                      default: whatsapp
                      description: >-
                        선호하는 전송 채널입니다. 대상 국가 또는 번호에서 해당 채널을 사용할 수 없는 경우 메시지는
                        자동으로 SMS로 대체되며, 발송은 계속 `Success`로 보고됩니다.
                    use_white_label_customization:
                      type: boolean
                      default: false
                      description: >-
                        When `true`, the send is white-labelled: if your
                        application has no SMS sender name, the SMS names your
                        white-label public name instead ("Acme Bank의 인증 코드는
                        123456입니다"). Your SMS sender name, when set, is used
                        with or without this flag. Applies to SMS messages,
                        including an SMS fallback from another channel; WhatsApp
                        codes are sent with a fixed message and are not branded.
                        Defaults to `false`.
                    sms_sender_name:
                      type: string
                      nullable: true
                      maxLength: 30
                      example: Acme Bank
                      description: >-
                        애플리케이션의 SMS 발신자 이름 대신 이 코드의 SMS에 표시되는 이름("123456 is your
                        verification code for Acme Bank")입니다. 무료입니다. 1~30자: 문자,
                        숫자, 공백 및 ' & - !만 허용되며, 숫자로만 구성될 수 없고, 단어 사이에 단일 공백만
                        허용됩니다. 그 외의 값은 `400`을 반환하며 코드가 전송되지 않습니다. 생략되거나 `null`
                        또는 빈 값인 경우 애플리케이션의 SMS 발신자 이름이 사용됩니다. 각 애플리케이션은 하루(UTC)에
                        최대 2개의 새 이름을 사용하기 시작할 수 있으며, 이를 초과하면 애플리케이션 이름으로 코드가
                        전송됩니다. 다른 채널의 SMS 폴백을 포함한 SMS 메시지에 적용되며, WhatsApp 코드는
                        브랜드가 지정되지 않습니다.
                      pattern: ^$|^(?![\d ]+$)[\p{L}\p{N}'&!-]+( [\p{L}\p{N}'&!-]+)*$
                signals:
                  type: object
                  description: >-
                    최종 사용자에 대한 선택적 기기 및 네트워크 신호로, 어뷰징 또는 자동화된 트래픽 감지를 개선하기 위해 사기
                    방지 계층으로 전달됩니다. 모든 필드는 선택 사항입니다.
                  properties:
                    ip:
                      type: string
                      description: 최종 사용자 기기의 주소입니다. IPv4 또는 IPv6입니다.
                      example: 192.0.2.1
                    device_id:
                      type: string
                      maxLength: 255
                      description: >-
                        최종 사용자 기기의 고유 식별자입니다. Android: `ANDROID_ID`, iOS:
                        `identifierForVendor`.
                      example: 8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2
                    device_platform:
                      type: string
                      enum:
                        - android
                        - ios
                        - ipados
                        - tvos
                        - web
                      description: 최종 사용자 기기의 플랫폼입니다.
                    device_model:
                      type: string
                      maxLength: 255
                      description: 최종 사용자 기기의 모델입니다.
                      example: iPhone17,2
                    os_version:
                      type: string
                      maxLength: 64
                      description: 최종 사용자 기기의 운영체제 버전입니다.
                      example: 18.0.1
                    app_version:
                      type: string
                      maxLength: 64
                      description: 애플리케이션의 버전입니다.
                      example: 1.2.34
                    user_agent:
                      type: string
                      maxLength: 512
                      description: 최종 사용자의 브라우저 또는 앱의 사용자 에이전트입니다.
                      example: >-
                        Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X)
                        AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3
                        Mobile/15E148 Safari/604.1
                vendor_data:
                  type: string
                  description: >-
                    세션에 유지되고 전송 응답, 일치 확인 응답, webhook 및 Business Console에 그대로
                    반환되는 선택적 호출자 제어 식별자(내부 사용자 ID, 이메일, UUID 등)입니다. Didit의
                    `request_id`를 사용자 레코드와 연결하는 데 사용하십시오.
                metadata:
                  type: object
                  nullable: true
                  description: >-
                    세션에 유지되고 전송 응답, 일치 확인 응답, webhook 및 Business Console에 다시
                    반환되는 선택적 자유 형식 JSON 객체입니다.
              required:
                - phone_number
            examples:
              WhatsApp (default):
                summary: WhatsApp을 통한 6자리 OTP(SMS로 자동 대체)
                value:
                  phone_number: '+14155552671'
                  options:
                    preferred_channel: whatsapp
                    locale: en-US
                  vendor_data: user-1234
              SMS with custom code length:
                summary: 4자리 코드로 SMS 전송 강제
                value:
                  phone_number: '+34699999999'
                  options:
                    preferred_channel: sms
                    code_size: 4
                    locale: es
              With fraud signals:
                summary: 기기 신호를 전달하여 사기 방지 스크리닝을 강화합니다.
                value:
                  phone_number: '+14155552671'
                  signals:
                    ip: 192.0.2.1
                    device_id: 8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2
                    device_platform: ios
                    device_model: iPhone17,2
                    os_version: 18.0.1
                    app_version: 1.2.34
                  vendor_data: user-1234
      responses:
        '200':
          description: >-
            전송이 확인되었습니다. `status`를 확인하십시오. `Success` 및 `Retry`는 코드가 발송 중임을 의미하며,
            `Blocked`는 사기 방지 계층에서 거부되어 인증이 이미 `Declined`로 완료되었음을 의미합니다.
            `request_id`는 유지되는 세션 ID입니다(`Retry` 시 동일한 ID).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhoneVerificationSendResponse'
              examples:
                Success:
                  summary: 새 인증을 위해 전송된 OTP
                  value:
                    request_id: e39cb057-92fc-4b59-b84e-02fec29a0f24
                    status: Success
                    reason: null
                    vendor_data: user-1234
                    metadata: null
                Retry:
                  summary: 5분 기간 내 동일한 번호로 두 번째 발송 — 동일한 request_id
                  value:
                    request_id: e39cb057-92fc-4b59-b84e-02fec29a0f24
                    status: Retry
                    reason: null
                    vendor_data: user-1234
                    metadata: null
                Blocked:
                  summary: 사기 방지로 거부됨 — 인증이 '거부됨' 상태로 종료되었으며, 청구되지 않음
                  value:
                    request_id: 0d8af1f4-0c43-46d7-b75c-6e4e22c0a7b3
                    status: Blocked
                    reason: repeated_attempts
                    vendor_data: user-1234
                    metadata: null
        '400':
          description: >-
            유효성 검사 오류입니다. 형식이 잘못된 입력은 DRF의 필드 오류 봉투(문제가 있는 필드당 메시지 배열 1개, 옵션 오류의
            경우 `options` 아래에 중첩됨)를 반환합니다. 파싱은 되지만 전송 시점에 거부된 번호(도달할 수 없거나 단축 코드
            등 자격이 없는 회선 유형)는 대신 `{"detail": ...}` 봉투를 반환합니다.
          content:
            application/json:
              examples:
                Invalid phone number (field error):
                  summary: 유효한 E.164 번호가 아닙니다
                  value:
                    phone_number:
                      - Invalid phone number provided.
                Missing phone number:
                  summary: body에 `phone_number`가 포함되지 않음
                  value:
                    phone_number:
                      - This field is required.
                Invalid options:
                  summary: >-
                    범위를 벗어난 `code_size`, 잘못된 형식의 `locale`, 알 수 없는
                    `preferred_channel`
                  value:
                    options:
                      code_size:
                        - Ensure this value is less than or equal to 8.
                      locale:
                        - Ensure this field has no more than 5 characters.
                      preferred_channel:
                        - '"carrier_pigeon" is not a valid choice.'
                Number rejected at send time:
                  summary: 유효한 E.164 형식이지만 해당 번호로 OTP를 수신할 수 없습니다.
                  value:
                    detail: Invalid phone number provided.
                Ineligible line type:
                  summary: '회선 유형이 OTP를 수신할 수 없음(예: 단축 번호)'
                  value:
                    detail: Invalid phone line type provided.
        '403':
          description: >-
            권한이 거부되었습니다. `x-api-key` 헤더가 누락되었을 때 반환됩니다(`{"detail": ...}`).
            잘못되었거나 취소되었거나 만료된 키는 `401`을 반환합니다. 또한 발송 전에 조직이 충전한 적이 없거나(어뷰징 방지
            게이트) 잔액이 대상의 발송 가격을 충당할 수 없을 때도 반환됩니다(`{"error": ...}`).
          content:
            application/json:
              examples:
                Missing or invalid API key:
                  summary: '`x-api-key` 헤더가 없거나, 키가 유효하지 않거나 해지되었습니다'
                  value:
                    detail: You do not have permission to perform this action.
                Top-up required:
                  summary: 조직의 첫 충전 전까지 전화번호 인증이 비활성화 상태로 유지됨
                  value:
                    detail: >-
                      To protect against abuse, phone verification is disabled
                      until your first top-up.
                Not enough credits:
                  summary: 조직 잔액이 전송 가격을 충당할 수 없습니다
                  value:
                    error: You don't have enough credits to perform this request.
        '429':
          description: >-
            속도 제한을 초과했습니다. POST/PATCH/DELETE endpoint는 API 키당 분당 300회의 쓰기 요청 한도를
            공유합니다(거래 생성 및 이벤트 수집은 별도로 600회 한도 적용). 또한 상위 시스템에서 전화번호당 시간당 4회의 인증
            시도로 어뷰징 방지 상한이 적용됩니다. 응답에는 `X-RateLimit-Limit`,
            `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After` 헤더가
            포함됩니다. 참고: `X-RateLimit-*`/`Retry-After` 헤더는 분당 300회 쓰기 제한으로 인한 429
            응답에만 함께 제공되며, 번호당 상한으로 인한 429 응답에는 속도 제한 헤더가 포함되지 않습니다.
          content:
            application/json:
              examples:
                Per-number cap:
                  summary: 지난 1시간 동안 동일한 번호로 4회를 초과하는 인증 시도 발생
                  value:
                    detail: >-
                      Maximum verification attempts reached for this phone
                      number. Only 4 authentication attempts are allowed per
                      hour. Try again later or use a different number.
                Write rate limit exceeded:
                  summary: 현재 분 동안 300건을 초과하는 쓰기 요청 발생
                  value:
                    detail: >-
                      Write request rate limit exceeded. You can make up to 300
                      requests per minute.
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '500':
          description: 알려진 제공업체 중단이 아닌 인증 생성 중 예기치 않은 오류가 발생했습니다. 안전하게 재시도할 수 있습니다.
          content:
            application/json:
              examples:
                Provider error:
                  summary: OTP 전송을 시작할 수 없습니다
                  value:
                    detail: Error creating phone verification
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '502':
          description: >-
            전화번호 인증 공급자를 일시적으로 사용할 수 없습니다(5xx 응답, 시간 초과 또는 내장 재시도 후에도 지속된 연결
            실패). 다시 시도해도 안전하며, 비용이 청구되지 않고 시도 횟수도 차감되지 않습니다.
          content:
            application/json:
              examples:
                Provider outage:
                  summary: 공급자가 발송 요청에 응답하지 않았습니다
                  value:
                    detail: >-
                      Phone verification is temporarily unavailable. Please try
                      again shortly.
                    code: phone_provider_unavailable
              schema:
                type: object
                properties:
                  detail:
                    type: string
                  code:
                    type: string
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/phone/send/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "phone_number": "+14155552671",
                "options": {
                  "code_size": 6,
                  "preferred_channel": "whatsapp",
                  "locale": "en-US"
                },
                "vendor_data": "user-1234"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.phone.send_code(
                phone_number="+14155552671",
                options={
                    "locale": "en-US",
                    "preferred_channel": "whatsapp",
                },
                vendor_data="user-1234",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.phone.sendCode({
              phone_number: "+14155552671",
              options: {
                locale: "en-US",
                preferred_channel: "whatsapp",
              },
              vendor_data: "user-1234",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.SendCode(ctx, didit.PhoneSendCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tOptions: didit.Some(didit.PhoneSendCodeParamsOptions{\n\t\tLocale:           didit.String(\"en-US\"),\n\t\tPreferredChannel: didit.Some(didit.PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.PhoneSendCodeParams;

            // Reads DIDIT_API_KEY.
            Didit client = new Didit();

            var result = client.phone().sendCode(PhoneSendCodeParams.builder()
                    .phoneNumber("+14155552671")
                    .options(PhoneSendCodeParams.Options.builder()
                            .locale("en-US")
                            .preferredChannel(PhoneSendCodeParams.Options.PreferredChannel.of("whatsapp"))
                            .build())
                    .vendorData("user-1234")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->phone->sendCode([
                'phone_number' => '+14155552671',
                'options' => [
                    'locale' => 'en-US',
                    'preferred_channel' => 'whatsapp',
                ],
                'vendor_data' => 'user-1234',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.phone.send_code(
              phone_number: "+14155552671",
              options: {
                locale: "en-US",
                preferred_channel: "whatsapp",
              },
              vendor_data: "user-1234"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await client.Phone.SendCodeAsync(new
            PhoneSendCodeParams

            {
                PhoneNumber = "+14155552671",
                Options = new PhoneSendCodeParamsOptions
                {
                    Locale = "en-US",
                    PreferredChannel = new PhoneSendCodeParamsOptionsPreferredChannel("whatsapp"),
                },
                VendorData = "user-1234",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    PhoneVerificationSendResponse:
      type: object
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            인증의 세션 id입니다. `Retry` 전송은 최초 전송과 동일한 `request_id`를 반환합니다. 이 id는
            Business Console에 표시되며, 완료된 `POST /v3/phone/check/`에 의해 다시 반환되고,
            `GET /v3/session/{sessionId}/decision/`에 전달할 수 있습니다.
        status:
          type: string
          enum:
            - Success
            - Retry
            - Blocked
          description: >-
            `Success` — 새 인증에 OTP가 전송되었습니다. `Retry` — 이전 전송으로 생성된 대기 중인 인증에 OTP가
            재전송되었습니다. `Blocked` — 사기 방지 계층에서 전송을 거부했습니다. 인증은 즉시 `Declined` 상태로
            완료 처리되며 요금은 청구되지 않습니다.
        reason:
          type: string
          nullable: true
          description: >-
            발송이 `Blocked`된 이유입니다(예: `repeated_attempts`, `suspicious`, `spam`).
            `Success` 및 `Retry`에서는 `null`입니다.
        vendor_data:
          type: string
          nullable: true
          description: 세션에 저장된 `vendor_data`의 에코 값입니다(첫 전송 기준).
        metadata:
          type: object
          nullable: true
          description: 세션에 저장된 `metadata`의 에코 값입니다(첫 전송 기준).
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Business Console의 Developers -> API keys에서 발급받은 귀하 애플리케이션의 API 키입니다. 기본
        키는 전체 접근 권한을 갖습니다. 이름이 지정된 키는 리소스별 none, read, write 범위로 권한을 제한할 수 있으며
        특정 워크플로나 승인된 세션, IP 주소 목록, 만료일 등으로 제한할 수도 있습니다. 401은 키가 잘못되었거나 폐기되었거나
        만료되었음을 의미합니다. 403은 키가 전송되지 않았거나, 키에 해당 리소스나 작업에 대한 접근 권한이 없거나, 요청이 허용된
        IP 목록 외부 주소에서 발생했음을 의미합니다. 세션 경로에서의 404는 해당 세션이 키의 허용 워크플로 또는 상태 범위를
        벗어났음을 의미합니다. 미디어 접근 권한이 없는 키는 이미지, 비디오, PDF URL을 null로 수신하며, 세션 write
        권한이 없는 키는 세션 링크와 token을 null로 수신합니다.
        https://docs.didit.me/console/api-keys 를 참고하십시오.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.