Verify Users
Verify phone numbers and email addresses instantly — no Twilio account, no vendor onboarding, just a single API call.
Quick Example
Section titled “Quick Example”import { withSapiom } from "@sapiom/axios";import axios from "axios";
const client = withSapiom(axios.create(), { apiKey: process.env.SAPIOM_API_KEY,});
const baseUrl = "https://prelude.services.sapiom.ai";
// Step 1: Send a verification codeconst { data: sendData } = await client.post(`${baseUrl}/verifications`, { target: { type: "phone_number", value: "+15551234567", },});
console.log("Verification sent:", sendData.id);
// Step 2: Check the code (after user enters it)const { data: checkData } = await client.post(`${baseUrl}/verifications/check`, { verificationRequestId: sendData.id, code: "123456", // code entered by user});
console.log("Verified:", checkData.status === "success");import { createFetch } from "@sapiom/fetch";
const fetch = createFetch({ apiKey: process.env.SAPIOM_API_KEY,});
const baseUrl = "https://prelude.services.sapiom.ai";
// Step 1: Send a verification codeconst sendResponse = await fetch(`${baseUrl}/verifications`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ target: { type: "phone_number", value: "+15551234567", }, }),});
const sendData = await sendResponse.json();console.log("Verification sent:", sendData.id);
// Step 2: Check the code (after user enters it)const checkResponse = await fetch(`${baseUrl}/verifications/check`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ verificationRequestId: sendData.id, code: "123456", // code entered by user }),});
const checkData = await checkResponse.json();console.log("Verified:", checkData.status === "success");How It Works
Section titled “How It Works”When you send a verification request, Sapiom routes it to Prelude, a verification service that handles SMS and email delivery. The SDK automatically handles payment negotiation so you don’t need a separate Prelude account.
The verification flow has two steps:
- Send a code — Call the
/verificationsendpoint with a phone number or email. The user receives a 6-digit code. - Check the code — When the user enters the code, call
/verifications/checkto verify it. This endpoint is free and rate-limited.
Verification codes expire after 10 minutes. If the user doesn’t receive the code or it expires, send a new verification request.
Provider
Section titled “Provider”Powered by Prelude. Prelude handles global SMS delivery with high deliverability and fraud prevention built in.
API Reference
Section titled “API Reference”Send Verification Code
Section titled “Send Verification Code”Endpoint: POST https://prelude.services.sapiom.ai/verifications
Send a verification code to a phone number or email address.
Request
Section titled “Request”| Parameter | Type | Required | Description |
|---|---|---|---|
target.type | string | Yes | phone_number or email_address |
target.value | string | Yes | Phone number (E.164 format) or email address |
signals | object | No | Additional signals for fraud detection |
options | object | No | Verification options |
metadata | object | No | Custom metadata to store with request |
Phone number format: Use international E.164 format with country code (e.g., +15551234567 for US, +442071234567 for UK).
{ "target": { "type": "phone_number", "value": "+15551234567" }}{ "target": { "type": "email_address", }}Response
Section titled “Response”{ "id": "550e8400-e29b-41d4-a716-446655440000", "status": "pending"}Save the id — you’ll need it to check the code.
Check Verification Code
Section titled “Check Verification Code”Endpoint: POST https://prelude.services.sapiom.ai/verifications/check
Verify the code entered by the user. This endpoint is free but rate-limited to prevent brute-force attacks.
Request
Section titled “Request”| Parameter | Type | Required | Description |
|---|---|---|---|
verificationRequestId | string | Yes | The id from the send response |
code | string | Yes | 4-8 digit verification code |
{ "verificationRequestId": "550e8400-e29b-41d4-a716-446655440000", "code": "123456"}Response
Section titled “Response”{ "id": "660e8400-e29b-41d4-a716-446655440001", "status": "success"}| Status | Description |
|---|---|
success | Code is correct, verification complete |
pending | Verification still in progress |
failure | Code is incorrect |
Error Codes
Section titled “Error Codes”| Code | Description |
|---|---|
| 400 | Invalid phone number, email, or code format |
| 402 | Payment required — ensure you’re using the Sapiom SDK |
| 404 | Verification request not found |
| 410 | Verification code has expired |
| 422 | Invalid verification code (wrong code entered) |
| 429 | Rate limit exceeded on check endpoint |
Complete Example
Section titled “Complete Example”import { withSapiom } from "@sapiom/axios";import axios from "axios";
const client = withSapiom(axios.create(), { apiKey: process.env.SAPIOM_API_KEY,});
const baseUrl = "https://prelude.services.sapiom.ai";
async function verifyPhoneNumber(phoneNumber: string, userCode: string) { // Step 1: Send verification code const sendResponse = await client.post(`${baseUrl}/verifications`, { target: { type: "phone_number", value: phoneNumber, }, });
const verificationId = sendResponse.data.id; console.log(`Verification code sent to ${phoneNumber}`);
// Step 2: Check the code (after user enters it) const checkResponse = await client.post(`${baseUrl}/verifications/check`, { verificationRequestId: verificationId, code: userCode, });
return checkResponse.data.status === "success";}
// Usageconst isVerified = await verifyPhoneNumber("+15551234567", "123456");console.log("Verified:", isVerified);import { createFetch } from "@sapiom/fetch";
const fetch = createFetch({ apiKey: process.env.SAPIOM_API_KEY,});
const baseUrl = "https://prelude.services.sapiom.ai";
async function verifyPhoneNumber(phoneNumber: string, userCode: string) { // Step 1: Send verification code const sendResponse = await fetch(`${baseUrl}/verifications`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ target: { type: "phone_number", value: phoneNumber, }, }), });
const sendData = await sendResponse.json(); const verificationId = sendData.id; console.log(`Verification code sent to ${phoneNumber}`);
// Step 2: Check the code (after user enters it) const checkResponse = await fetch(`${baseUrl}/verifications/check`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ verificationRequestId: verificationId, code: userCode, }), });
const checkData = await checkResponse.json(); return checkData.status === "success";}
// Usageconst isVerified = await verifyPhoneNumber("+15551234567", "123456");console.log("Verified:", isVerified);Pricing
Section titled “Pricing”| Operation | Cost |
|---|---|
| Send verification code | $0.015 (1.5 cents) |
| Check verification code | Free |