Send and verify a code
Surge's verification API sends a six-digit code to a phone number and then checks the code the user provides. It handles code generation, delivery, retry limits, and expiration — you don't manage any of that yourself.
How it works
Verification is a two-step flow:
- Create a verification — Surge sends a six-digit code to the number
- Check the code — Surge validates the code the user entered
POST /verifications → creates the verification, sends the code
POST /verifications/:id/checks → validates the user's inputStep 1 — Send the code
curl -X POST https://api.surge.app/verifications \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+18015551234"
}'{
"id": "vfn_01jrzhe8d9enptypyx360pcmxj",
"phone_number": "+18015551234",
"status": "pending",
"attempt_count": 0
}The user receives a text like: "Your verification code is 847291. It expires in 10 minutes."
Step 2 — Check the code
When the user submits the code in your UI, send it to Surge for verification:
curl -X POST https://api.surge.app/verifications/VERIFICATION_ID/checks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "847291"
}'The response includes a result field indicating whether the verification succeeded:
{
"result": "ok",
"verification": {
"id": "vfn_01jrzhe8d9enptypyx360pcmxj",
"phone_number": "+18015551234",
"status": "verified",
"attempt_count": 1
}
}Limits
- Expiration: 10 minutes from creation. After that, the verification moves to
expiredstatus and all check attempts returnexpired. - Max attempts: 3 incorrect guesses per verification. After 3 incorrect attempts, the verification moves to
exhaustedstatus. Create a new verification and prompt the user to resend the code.
Result values
| Result | Meaning | What to do |
|---|---|---|
ok | Code matched | Grant access |
incorrect | Wrong code | Show an error, let the user retry |
expired | Code is more than 10 minutes old | Prompt user to request a new code |
already_verified | This verification was already approved | Treat as ok (idempotent) |
exhausted | 3 incorrect attempts reached | Create a new verification; do not retry the same one |
Putting it together
A complete flow in Python:
from surge import Surge
surge = Surge()
# User enters their phone number
response = surge.verifications.create(phone_number="+18015551234")
verification_id = response.id
# Later: user submits the code
check = surge.verifications.check(
id=verification_id,
code=user_submitted_code
)
match check.result:
case "ok" | "already_verified":
# Grant access
await grant_access(user)
case "incorrect":
return {"error": "Incorrect code. Please try again."}
case "expired":
return {"error": "Code expired. Request a new one."}
case "exhausted":
return {"error": "Too many attempts. Please request a new code."}For deliverability quirks and edge cases, see Usage patterns.