Checked against a hash
The check uses a keyed hash of the code and of the client IP. A code in a sent email is removed after delivery, and SMS text is never stored.
Send a one-time code to a phone or an inbox, let Notix turn away risky requests before they cost you, and check what the user typed in one more call. No code is ever stored in plain text.
Keep the id from the first call. Pass it back with what the user typed, and the answer says whether it matched and how many tries are left.
import { Notix } from "notix-js";
const notix = new Notix(process.env.NOTIX_API_KEY);
// 1. Send. Email is the default channel.
const { data: sent } = await notix.verify.send({
to: "+2348031234471",
channel: "sms",
appName: "Acme",
clientIp: request.ip,
});
// 2. Check what the user typed.
const { data: result } = await notix.verify.check({
id: sent.id,
code: "482913",
});
if (result?.verified) signIn(user);
import os
from notix import Notix
notix = Notix(os.environ["NOTIX_API_KEY"])
sent, err = notix.verify.send({
"to": "maria@example.com",
"appName": "Acme",
})
result, err = notix.verify.check({"id": sent["id"], "code": "482913"})
<?php
use Notix\Notix;
$notix = new Notix(getenv('NOTIX_API_KEY'));
$sent = $notix->verify->send([
'to' => 'maria@example.com',
'appName' => 'Acme',
], $_SERVER['REMOTE_ADDR']);
$result = $notix->verify->check(['id' => $sent['id'], 'code' => '482913']);
curl -X POST https://app.usenotix.dev/api/v1/verify/send \
-H "Authorization: Bearer $NOTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "maria@example.com", "appName": "Acme" }'
curl -X POST https://app.usenotix.dev/api/v1/verify/check \
-H "Authorization: Bearer $NOTIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "id": "ver_8f3k2", "code": "482913" }'
Bots that pump your SMS bill and throwaway sign-ups are stopped at the door. Pick a request to see what fires.
Each signal that fires adds to a score out of 100. The answer carries the score, the level (Low, Medium or High) and every signal, so your app can decide what to do with a Medium.
clientIp so the per address check can countSent, with a High score in the answer. Strict mode would refuse it. Scores use the default weights, which the Notix team can tune.
A refused request costs nothing and creates no code. The answer names the signal, so you can tell the user to try a different address rather than showing a vague error.
HTTP/1.1 422 Unprocessable Entity
{
"error": {
"code": "RISK_REFUSED",
"message": "Verification refused: Disposable email domain."
},
"risk": {
"score": 70,
"level": "HIGH",
"reasons": [
{ "code": "disposable_domain", "detail": "Disposable email domain." }
]
}
}
The One-time codes page shows the week at a glance and each code with its channel, risk, tries and status.
Codes sent, verified, the average time to enter one and how many were blocked, with a funnel from sent to verified. Filter by channel. The same figures come from the API with notix.verify.list() and notix.verify.stats().
Your server can follow each code too, with the webhook events verification.sent, verification.verified, verification.failed, verification.refused and verification.delivered.
Send email codes from your own address with your own subject, or with a template your team designs in the console. SMS codes can use your approved sender ID.
await notix.verify.send({
to: "maria@example.com",
appName: "Acme",
codeLength: 8, // 4 to 8 digits
expiresIn: 300, // 60 to 1800 seconds
from: "Acme <security@acme.com>",
templateId: "sign-in-code", // uses {{code}}, {{appName}}, {{expiresMinutes}}
});
The check uses a keyed hash of the code and of the client IP. A code in a sent email is removed after delivery, and SMS text is never stored.
SMS codes are billed like any text, in naira, shillings or dollars, with no paid plan needed.
SMS codes report delivery back, so verification.delivered tells you the code reached the phone.
Send, batch, schedule and retry safely with idempotency keys, then follow every message through logs, events and signed webhooks.
Explore Email APISigned webhook events for email, contacts, domains, SMS and inbound mail, retried when your endpoint is down, with every delivery logged.
Explore WebhooksSPF, DKIM and DMARC records ready to publish, one-click DNS with Domain Connect, and a domain that pauses itself before bounces hurt it.
Explore DeliverabilityMore on sending and deliverability on the Notix blog.
Verify a domain, copy an API key, make one call. The free plan does not ask for a card.