Why this exists
SMS verification breaks in small ways: codes arrive late, expire early, get rate-limited, or fail on certain country formats. Most of these bugs only show up with real inbound SMS, not mocks.
| Failure mode | What users see |
|---|---|
| Slow delivery | Code never appears before they abandon |
| Early expiry | “Invalid or expired code” after a resend |
| Rate limits | Temporary blocks after spam-clicking resend |
| Format mismatch | Country picker and dialing code disagree |
| Log leaks | OTP strings land in analytics or error trackers |
How to use it
- Work through the checklist on a staging build that can send real SMS.
- Record p50 / p95 delivery time for at least one country.
- Fail the release if any security or privacy item is unchecked.
- Prefer passkeys or authenticator apps for high-risk actions once the SMS path is proven.
Checklist
Input and formatting
Delivery
Validation
Security and privacy
Suggested test matrix
Run at least one happy path and one failure path per row before release.
| Scenario | Assert |
|---|---|
| Domestic long number | Code arrives within SLO; E.164 paste works |
| International number | Country picker and dial code stay aligned |
| Immediate resend | Cooldown shows; previous code is rejected |
| Expired code | Clear expired/invalid message; new code works |
| Provider reject | Readable error; no silent hang |
| Log / analytics spot check | OTP string never appears in events or traces |
Testing with real inbound SMS
Temporary inbound numbers help you exercise live carrier routes across countries without tying QA to personal SIMs.
See the QA checklist write-up and the SMS verification API guide. Only test apps you own or are authorized to test.
Pass criteria
Treat the release as not ready if any security or privacy box is unchecked, if p95 delivery exceeds your product SLO, or if resend does not invalidate the previous code.