One-time codes, without the toll fraud.
coss.com Verify is a one-time code API that proves someone has a phone number or mailbox, with a fraud guard that stops SMS pumping before you pay.
How it works
Your backend makes two calls. coss.com makes the code, sends it, counts the attempts and expires it.
// 1. The user typed their number: send them a code.
const { : , } = await ..({
: "+14155550123", // or an email address
: , // the end user's address, for the fraud guard
: "user_42",
});
if (?. === "verification_blocked") {
// The fraud guard stopped it: nothing was sent or billed.
}
// 2. They typed the code they got: check it.
const { : } = await ..({ : "+14155550123", : });
if (?.) {
// The number is theirs.
}A wrong code spends an attempt, and the last one fails the verification. Checking an approved verification again with its code stays valid until it expires, and is billed once. See the Verify guide and the API reference.
Codes without the plumbing
Everything between asking for a code and knowing it is them, behind one key.
SMS or email
A number in E.164 form gets an SMS, an email address an email. SMS go from coss.com's shared numbers or one of your own registered numbers; email from your verified domain or from coss.com's sender. See SMS codes and email codes.
Never stored, never logged
coss.com keeps only an HMAC of each code, until the verification expires, and erases the message text once it is sent. Codes never appear in logs, webhooks or email subjects.
Resends that just work
Starting again for a pending destination sends a new code, retires the old one and restarts the expiry, up to 5 codes per verification. No resend endpoint, no state on your side.
A fraud guard that runs first
Each new verification is checked before a code goes out: your Risk lists, premium-rate and non-mobile numbers, Tor, and velocity per IP, user, number prefix and country. A blocked one costs nothing. See the fraud guard.
Allowed countries
SMS codes go only to the countries in the environment's Verify settings, the US and Canada by default. Anything else fails with country_not_allowed before a message is sent.
Stops SMS pumping before you pay for it
Pumping is codes requested for numbers whose owners earn money from every text. Nobody ever enters them.
The fraud guard watches for exactly that. It blocks premium-rate and shared-cost numbers, and numbers that can't receive a text. It counts verifications per number prefix (the number without its last four digits) and per country, and compares them with how many were approved: real people enter their codes, pumping never does. A burst to one prefix, or a prefix or country whose codes are rarely entered, is blocked with a reason such as verify.prefix_low_conversion.
It uses Risk's building blocks and your environment's Risk lists, where an allow-list entry wins. It never blocks on a signal it couldn't read. Each destination also gets at most 5 codes every 10 minutes, so a looping form stops on its own.
Specifications
The defaults of an environment without settings, and what each setting allows.
- Code length
- 6 digits by default, 4 to 10
- Code lifetime
- 10 minutes by default, 1 to 30 minutes
- Wrong codes allowed
- 5 by default, 1 to 10
- Codes per verification
- 5, the first and its resends
- Codes per destination
- 5 every 10 minutes
- Default SMS countries
- US and Canada
- Stored
- an HMAC of the code, until it expires
- Verifications kept
- 30 days
- Sandbox codes
- always zeros
Pricing
You pay per approved verification, plus the channel. Blocked, failed and expired ones cost only the messages actually sent.
Questions
- How do I add phone verification with coss.com?
- Call coss.verify.start() with the phone number and the end user's IP address, then coss.verify.check() with the code they typed. coss.com makes the code, sends it, counts the attempts and expires it; only valid true from the check proves the number is theirs.
- Can Verify send codes by email?
- Yes. Start a verification with an email address instead of a phone number and the code goes by email, from an address on one of your verified domains or from coss.com's sender as "your app via coss.com". The code is never in the subject, and the email has no links or tracking.
- How does coss.com stop SMS pumping?
- Every new verification passes a fraud guard before a code is sent. It blocks premium-rate and non-mobile numbers, Tor exit nodes, entries on your Risk block list, bursts from one IP address, user or number prefix, and prefixes or countries whose codes are rarely entered. A blocked verification is stored with its reasons, and nothing is sent or billed.
- Does coss.com store the verification code?
- No. Only an HMAC of the code is kept, until the verification expires, and the text of the SMS or email is erased once it is sent. The code never appears in logs or webhooks.
- What happens if a user asks for the code again?
- Starting a verification for the same destination while one is pending sends a new code, the earlier one stops working and the expiry restarts. A verification can send at most 5 codes.
- How is Verify priced?
- You pay per approved verification, plus the channel. An SMS from coss.com's shared numbers is billed at its country's SMS rate, one from your own number like any SMS, and email codes cost nothing extra. Blocked, failed and expired verifications cost only the messages actually sent. The pricing page lists the rates.
- How do I test Verify without sending real codes?
- Use a sandbox key. The code is always zeros, such as 000000 with the default length, SMS go to the SMS simulator and emails to the sandbox's fake provider, and nothing is billed. The fraud guard still runs, so a premium-rate test number is blocked as in live environments.
Works with
- SMScoss.com SMS is an API that sends and receives text messages from your own phone numbers, with US 10DLC and toll-free registration done for you.
- Riskcoss.com Risk is a fraud and abuse API. It scores sign-ups, logins, checkouts and messages and answers allow, review or block, with the reasons why.
- Emailcoss.com Email is a transactional email API. Send single, batch and scheduled email from your domains, with templates, tracking and per-recipient webhooks.
- Rate limitingcoss.com rate limiting is a hosted rate limiter for your own endpoints. Define buckets once and check any key, a user, email or IP, with one call.
- Authenticationcoss.com covers sign-up, login and verification with account emails for Better Auth and Auth.js, one-time codes with a fraud guard, risk checks and rate limits.
Compared
Start with Verify today.
Development keys record every request and event and deliver nothing, so you can build and test before you verify a domain. Hand your coding agent this prompt:
Add coss.com to this project: read https://coss.com/llms.txt, get a development key with `npx coss-cli init --agents`, and build and test with it.