Android向けOTP API

AIコーダー向けのSMSによる電話番号認証とOTP

Claude Code、Cursor、Windsurfから、あるいは生のHTTPから、どんなプロジェクトにもSMS認証を組み込めます。コードはペアリング済みのAndroidから送信され、比較は定数時間で行われ、1番号あたり1日5コードの厳格な上限が悪用を根元から断ちます。

すべてのOTPを自在にカスタマイズ
長さ 4〜8 有効期間 60秒〜15分 試行回数 1〜10 クールダウン 30秒〜10分 リクエストごとのテンプレート 端末 / SIMルーティング
仕組み

2つのエンドポイント、往復1回

AIアシスタントがMCP経由で呼び出しても、外部クライアントがHTTPSで呼び出しても、ご自身のバックエンドが呼び出しても、ロジックは同じです。

STEP 01

send_otp

コードを生成し、有効期間と試行回数カウンターとともにハッシュを保存し、ペアリング済みのAndroid経由でSMSをプッシュします。

STEP 02

ユーザーが受信

ユーザーが端末でSMSを読み、認証フォームにコードを入力します。

STEP 03

verify_otp

最後に発行したコードと定数時間で比較します。verifiedと、失敗時には残り試行回数を返します。

エンドポイント

POSTのみ、Bearer認証

GETは405を返します。Cookieは無視されます。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}
  • その他の理由: expirednot_foundmax_attempts
curl例

コピペで使える呼び出し例

OTPを送信

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

# デフォルト値を上書き:
#   -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=+81901234567" \
  -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。

再送クールダウン

同じ番号への2回の送信の間隔は30〜600秒。デフォルトは60秒。

SMSテンプレート

ブランドのトーンに合わせて文章を調整できます。唯一の制約は{code}プレースホルダーを残すことです。

値を編集

ライブプレビューが変更を反映します。実際の番号にOTPを送信してフローを試せます。

OTP設定を開く →

セキュリティモデル

顧客を守るハードコードされた上限

番号ごとに1日5OTP

最も厳しい上限です。アカウントから変更できません。キーが漏洩しても、どの番号も24時間スライディングウィンドウで5件を超えるコードを受信することはありません。

トランザクション制御

クールダウンと24時間上限はSELECT ... FOR UPDATEで処理されます。並列の呼び出しが回避することはできません。

定数時間検証

verify_otpはhash_equalsを使用します。タイミングリークはありません。

POSTのみ、Cookieなし

両エンドポイントへのGETは405を返します。認証ではCookieは無視されます。画像タグ経由の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はOTPをペアリングされたAndroidとSIMから送信するため、A2P 10DLC登録は不要です。

アシスタント自身でOTPを追加できますか?

はい。Claude Code向けに同梱されているSkillが、いつsend_otpverify_otpを呼び出すかをアシスタントに教えます。「/signupに認証を追加してください」のようなプロンプトで十分です。

60秒で電話番号認証を追加

無料アカウントを作成し、OTP値を設定し、アシスタントにアプリへの認証組み込みを任せましょう。