안드로이드용 OTP API

AI 코더를 위한 SMS OTP 및 전화번호 인증

Claude Code, Cursor, Windsurf 또는 일반 HTTP로 모든 프로젝트에 SMS 인증을 통합하세요. 코드는 페어링된 본인의 안드로이드를 통해 발송되며, 비교는 상수 시간 안에 수행되고, 24시간당 번호 하나에 5회라는 엄격한 한도가 남용을 원천 차단합니다.

모든 OTP를 자유롭게 설정
길이 4 ~ 8 유효 시간 60초 ~ 15분 시도 횟수 1 ~ 10 쿨다운 30초 ~ 10분 요청별 템플릿 기기 / SIM 라우팅
동작 원리

두 개의 엔드포인트, 한 번의 왕복

호출이 MCP를 통한 AI 어시스턴트, HTTPS 외부 클라이언트, 또는 자체 백엔드에서 오더라도 동일한 로직이 적용됩니다.

단계 01

send_otp

코드를 생성하고 유효 시간과 시도 카운터와 함께 해시를 저장한 다음, 페어링된 본인의 안드로이드를 통해 SMS를 발송합니다.

단계 02

사용자가 코드를 수신

고객이 자신의 휴대폰에서 SMS를 확인하고 인증 폼에 코드를 입력합니다.

단계 03

verify_otp

가장 최근에 발급한 코드와 상수 시간 비교를 수행합니다. verified 값과 실패 시 남은 시도 횟수를 반환합니다.

엔드포인트

POST 전용, Bearer 인증

GET 요청은 405를 반환합니다. 쿠키는 무시됩니다. API 키가 URL이나 브라우저 히스토리에 남는 일은 없습니다.

발송 엔드포인트

POST https://app.sms8.io/ajax/otp-send.php

  • phone, 필수, E.164 형식
  • length, 4 ~ 8자리, 기본값 6
  • expires_in, 60 ~ 900초, 기본값 300
  • max_attempts, 1 ~ 10, 기본값 5
  • template, {code} 플레이스홀더가 포함된 텍스트
  • option / devices / useRandomDevice, 기기 선택

인증 엔드포인트

POST https://app.sms8.io/ajax/otp-verify.php

  • phone, 필수, E.164 형식
  • code, 사용자가 입력한 코드

응답:

  • 성공 시 {verified: true}
  • {verified: false, reason: "code_mismatch", attempts_left: 4}
  • 기타 사유: expired, not_found, max_attempts
curl 예제

바로 복사해서 쓸 수 있는 호출

OTP 발송

curl -X POST https://app.sms8.io/ajax/otp-send.php \
  -H "Authorization: Bearer YOUR_SMS8_API_KEY" \
  -d "phone=+821012345678"

# 기본값 재정의 :
#   -d "length=6"  -d "expires_in=300"
#   -d "max_attempts=5"
#   -d "template=인증번호는 {code}입니다. 곧 만료됩니다."

# 발신 기기 또는 SIM 선택 :
#   -d "option=0" --data-urlencode 'devices=["DEVICE_ID"]'
#   -d "option=1"               # 모든 기기에 분산
#   -d "option=2"               # 모든 SIM에 분산
#   -d "useRandomDevice=1"      # 무작위 발신자 선택

코드 인증

curl -X POST https://app.sms8.io/ajax/otp-verify.php \
  -H "Authorization: Bearer YOUR_SMS8_API_KEY" \
  -d "phone=+821012345678" \
  -d "code=123456"

# 성공: {"verified": true}
# 실패: {"verified": false, "reason": "code_mismatch", "attempts_left": 4}

AI 어시스턴트에서 (MCP)

Claude Code, Cursor 또는 Windsurf가 mcp.sms8.io에 연결되어 있다면 다음과 같이 요청하세요: "sms8 MCP를 통해 가입 플로우에 SMS 인증을 추가해줘". 어시스턴트는 기본값에 맞춰 send_otpverify_otp를 호출하고 기존 가입 또는 로그인 라우트에 통합합니다.

기본값 설정

대시보드에서 한 번에 설정

기본값은 한 번만 설정하면 됩니다. 호출 시 필드를 비워두면 자동으로 적용됩니다. 고정된 한도는 어떠한 경우에도 유지됩니다.

코드 길이

4 ~ 8자리. 기본값 6. 기억하기 쉬울 만큼 짧고, 무차별 대입 공격에 견딜 만큼 깁니다.

유효 시간

60 ~ 900초. 기본값 300 (5분). 재사용을 제한할 만큼 짧고, 사용자가 입력할 시간은 충분합니다.

인증 시도 횟수

코드가 잠기기 전 1 ~ 10회 시도. 기본값 5.

재발송 쿨다운

동일 번호로의 발송 간 30 ~ 600초. 기본값 60.

SMS 템플릿

브랜드 톤에 맞게 문구를 조정하세요. 한 가지 제약은 {code} 플레이스홀더를 유지하는 것입니다.

값 수정하기

실시간 미리보기는 모든 변경 사항을 반영합니다. 본인의 번호로 실제 OTP를 발송해 전체 흐름을 확인해 보세요.

OTP 설정 열기 →

보안 모델

고객을 보호하는 고정 한도

번호당 24시간 5개 OTP

가장 엄격한 한도입니다. 계정에서 변경할 수 없습니다. 키가 유출되어도 24시간 슬라이딩 윈도 내에서 어떤 번호도 5개를 초과해 받을 수 없습니다.

트랜잭션 검증

쿨다운과 24시간 한도는 SELECT ... FOR UPDATE 안에서 실행됩니다. 두 개의 병렬 호출이 한도를 우회할 수 없습니다.

상수 시간 인증

verify_otp는 hash_equals를 사용합니다. 타이밍 정보가 유출되지 않습니다.

POST 전용, 쿠키 없음

두 엔드포인트의 GET 요청은 405를 반환합니다. 인증에 쿠키는 사용되지 않습니다. 이미지 태그를 통한 CSRF가 불가능합니다.

OTP별 시도 한도

코드당 기본 5회 실패까지 허용됩니다. 그 이후에는 코드가 잠기고 새로운 send_otp가 필요합니다.

일반화된 오류 메시지

내부 예외는 Internal error를 반환합니다. 스택 트레이스가 클라이언트로 유출되지 않습니다.

FAQ

OTP 관련 질문

SMS8로 OTP를 어떻게 보내나요?

전화번호와 함께 https://app.sms8.io/ajax/otp-send.php로 POST 요청을 보내세요. 엔드포인트는 Authorization: Bearer 헤더를 수용합니다. 선택 필드: length (4 ~ 8), expires_in (60 ~ 900초), max_attempts (1 ~ 10), template, 그리고 기기 선택자.

verify_otp는 어떻게 동작하나요?

전화번호와 사용자가 입력한 코드를 https://app.sms8.io/ajax/otp-verify.php로 POST하세요. 서버는 가장 최근 OTP와 상수 시간 비교를 수행하고 verified: true 또는 verified: false를 반환합니다. 실패 시 reasonattempts_left도 함께 제공됩니다.

남용 방지 한도는 무엇인가요?

동일 번호는 24시간 슬라이딩 윈도 내 최대 5개의 OTP만 받습니다. 고정 한도이며, 계정에서 변경할 수 없고, 키가 유출되더라도 수신자를 보호합니다.

SMS8 OTP에 A2P 10DLC가 필요한가요?

아니요. SMS8은 페어링된 안드로이드와 SIM을 통해 OTP를 발송하므로 A2P 10DLC 등록이 필요하지 않습니다.

어시스턴트가 직접 OTP를 추가할 수 있나요?

네. Claude Code에 함께 제공되는 Skill이 어시스턴트에게 send_otpverify_otp를 언제 호출할지 학습시킵니다. "/signup에 인증을 추가해줘" 같은 프롬프트로 충분합니다.

60초 만에 전화번호 인증을 추가하세요

무료 계정을 만들고 OTP 기본값을 설정한 다음, 어시스턴트가 앱에 인증을 통합하도록 맡기세요.