Checking a number
before you send an OTP
Flag destination bursts and risky OTP attempts before you pay for another SMS.
Decision trace
Example · before an OTP sendDestination burst
- Input signalsSixth distinct number in one hour sharing a country and the first four national digits.
- Reason ids
prefix_burst - Decision
block - SendYour backend does not send the OTP
How it works
Check each attempt
Call once immediately before a proposed send, with a canonical E.164 number.
Read the decision
Get
allow,challengeorblockwith all matching reasons. Block takes precedence.Keep provider controls
Run this alongside tools such as Twilio Verify Fraud Guard, which it replaces none of.
API
Call from your backend. Supply the end-user IP from a trusted integration.
POST https://nolgard.com/v1/sms-check
Content-Type: application/json
{
"secret": "SITE_SECRET",
"phone": "+14155550100",
"accountId": "user_42",
"ip": "203.0.113.4",
"action": "signup"
}
// Example response: prefix burst
{
"decision": "block",
"reasons": ["prefix_burst"],
"country": "US"
}Limits
- This complements provider tools such as Twilio Verify Fraud Guard, spending limits and geo permissions. It does not replace them.
- Prefix bursts block the sixth distinct number in an hour. Sequential-number checks block at three distinct numbers within ±20 of the current number in an hour.
- The eleventh network-prefix attempt in an hour and sixth account attempt in 24 hours trigger a challenge. Those checks are skipped without
iporaccountId. - Counters are per site and count checked attempts, including retries and blocks; delivered messages are never counted.
actiondoes not partition them. - Destination risk is a static, conservative heuristic with no live carrier or premium-rate database behind it. E.164 syntax checks do not establish reachability, number assignment or SMS capability.
- Country comes from calling codes, with NANP and Kazakhstan disambiguation; other shared codes use the primary territory. Non-geographic networks have no country.
- Country allowlisting suppresses only the destination-risk challenge, never velocity checks. More than 120 checks per minute per site return 429.
- Phone and counter identities are stored as per-site HMACs. Counter storage failures can leave only static checks available.