Appearance
Verify a Code
POST /v1/verify/check
Submit the code that the user entered. Returns whether the code is valid.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | Yes | The recipient phone/email you sent the OTP to. SendAPI looks up the most recent pending OTP for this recipient. |
code | string | Yes | The code the user submitted. |
bash
curl -X POST https://sendapi.co/v1/verify/check \
-H "Authorization: Bearer sk_live_123456789" \
-H "Content-Type: application/json" \
-d '{
"to": "+447700900000",
"code": "847291"
}'javascript
const result = await client.verify.check({
to: '+447700900000',
code: userEnteredCode
});
if (result.valid) {
// Log the user in
} else {
console.log(`${result.attempts_remaining} attempts left`);
}python
result = client.verify.check(
to="+447700900000",
code=user_entered_code
)
if result.valid:
# log the user in
passSuccess Response
json
{
"success": true,
"data": {
"valid": true,
"status": "verified",
"attempts_remaining": 0
}
}Failed Response (Wrong Code)
json
{
"success": true,
"data": {
"valid": false,
"status": "pending",
"attempts_remaining": 2
}
}The status field reflects the underlying OTP record state. When the code is wrong but more attempts remain, status stays pending. When attempts are exhausted, status flips to failed. When the TTL has passed, status flips to expired.
Error Responses
| HTTP Code | Error Code | Reason |
|---|---|---|
404 | not_found | No pending OTP exists for this recipient (never sent, already verified, or expired and consumed) |
Security
After 5 failed attempts, the verification session is permanently invalidated. The user must request a new OTP to try again. This prevents brute-force attacks.