JavaScript / Node.js SDK
Installation
npm install @syvel/jsRequirements: Node.js 18+, modern browsers, Deno. Zero external dependencies.
Basic usage
import { Syvel } from "@syvel/js";
const syvel = new Syvel({ apiKey: "sv_your_key" });
try { // Check a full email address (analyzes local-part patterns too) const result = await syvel.checkEmail("user@yopmail.com");
console.log(result.risk_score); // 100 console.log(result.is_risky); // true console.log(result.reason); // "disposable"
// Or check a bare domain const domainResult = await syvel.check("yopmail.com");} catch { // API unavailable — let the user through}Response format
interface CheckResult { email: string; // Masked email (local part never exposed) is_risky: boolean; // true if risk_score exceeds your project threshold (default 65) risk_score: number; // 0–100 | 0–29 safe | 30–49 low | 50–79 warn | 80+ block reason: string; // "safe" | "disposable" | "undeliverable" | "role_account" deliverability_score: number; // 0–100 likelihood of successful delivery did_you_mean?: string; // Typo suggestion, e.g. "gmail.com" for "gmial.com" is_free_provider: boolean; // Gmail, Yahoo, etc. is_corporate_email: boolean; // Professional domain with business MX is_alias_email: boolean; // Privacy relay (SimpleLogin, etc.) mx_provider_label: string; // Human-readable MX provider name}Configuration
const syvel = new Syvel({ apiKey: "sv_your_key",
// Timeout in ms — default 3000. Keep it low: the API responds in < 300 ms. timeout: 3000,
// Silent mode: returns null on any error instead of throwing. // Enables automatic fail-open without a try/catch. silent: true,});With silent: true, errors return null instead of throwing:
const syvel = new Syvel({ apiKey: "sv_your_key", silent: true });
const result = await syvel.checkEmail("user@example.com");if (result?.is_risky) { // Block or warn}// If result is null, the API was unavailable — let the user through automaticallyError handling
import { Syvel, SyvelTimeoutError, SyvelAuthError, SyvelForbiddenError, SyvelValidationError, SyvelRateLimitError,} from "@syvel/js";
try { const result = await syvel.checkEmail("user@example.com");} catch (error) { if (error instanceof SyvelTimeoutError) { // Always fail open on timeout } else if (error instanceof SyvelRateLimitError) { // error.resetAt → ISO 8601 timestamp of quota reset // Always fail open on quota exceeded } else if (error instanceof SyvelValidationError) { // Malformed email or domain input } else if (error instanceof SyvelAuthError) { // Invalid or missing API key (401) } else if (error instanceof SyvelForbiddenError) { // Request origin not in your API key's allowed list (403) }}| Error class | HTTP | When to fail open |
|---|---|---|
SyvelTimeoutError | — | Always |
SyvelRateLimitError | 429 | Always — check resetAt |
SyvelAuthError | 401 | Fix your API key |
SyvelForbiddenError | 403 | Check allowed origins |
SyvelValidationError | 422 | Malformed input |
HTML form with real-time validation
<form id="signup-form"> <input type="email" id="email" placeholder="your@email.com" /> <p id="email-error" style="color: red; display: none;"></p> <button type="submit">Sign up</button></form>
<script type="module"> import { Syvel } from "https://cdn.jsdelivr.net/npm/@syvel/js";
const syvel = new Syvel({ apiKey: "sv_your_key", silent: true }); const emailInput = document.getElementById("email"); const emailError = document.getElementById("email-error"); let debounceTimer;
emailInput.addEventListener("input", () => { clearTimeout(debounceTimer); debounceTimer = setTimeout(async () => { const email = emailInput.value; if (!email.includes("@")) return;
const result = await syvel.checkEmail(email); if (result?.is_risky) { emailError.textContent = "Please use a professional email address."; emailError.style.display = "block"; } else { emailError.style.display = "none"; } }, 500); });</script>React hook
import { useState, useCallback } from "react";import { Syvel, type CheckResult } from "@syvel/js";
const syvel = new Syvel({ apiKey: import.meta.env.VITE_SYVEL_API_KEY, silent: true,});
export function useEmailCheck() { const [result, setResult] = useState<CheckResult | null>(null); const [loading, setLoading] = useState(false);
const check = useCallback(async (email: string) => { if (!email.includes("@")) return; setLoading(true); const data = await syvel.checkEmail(email); // null on any error (silent mode) setResult(data); setLoading(false); }, []);
return { result, loading, check };}React Hook Form
import { useForm } from "react-hook-form";import { Syvel } from "@syvel/js";
const syvel = new Syvel({ apiKey: "sv_your_key", silent: true });
function SignupForm() { const { register, handleSubmit, setError, formState: { errors } } = useForm();
const onSubmit = async (data: { email: string }) => { const result = await syvel.checkEmail(data.email); if (result?.is_risky) { setError("email", { message: "Please use a valid email address." }); return; } // Continue with registration };
return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("email")} type="email" /> {errors.email && <p>{errors.email.message}</p>} <button type="submit">Sign up</button> </form> );}Express
import express from "express";import { Syvel } from "@syvel/js";
const app = express();const syvel = new Syvel({ apiKey: process.env.SYVEL_API_KEY, silent: true });
app.post("/register", async (req, res) => { const result = await syvel.checkEmail(req.body.email);
if (result?.is_risky) { return res.status(422).json({ error: "Please use a professional email address." }); } // continue with registration…});Fastify
import Fastify from "fastify";import { Syvel } from "@syvel/js";
const app = Fastify();const syvel = new Syvel({ apiKey: process.env.SYVEL_API_KEY, silent: true });
app.post("/register", async (request, reply) => { const { email } = request.body as { email: string }; const result = await syvel.checkEmail(email);
if (result?.is_risky) { return reply.status(422).send({ error: "Please use a professional email address." }); } // continue with registration…});Next.js (Route Handler)
import { NextRequest, NextResponse } from "next/server";import { Syvel } from "@syvel/js";
const syvel = new Syvel({ apiKey: process.env.SYVEL_API_KEY, silent: true });
export async function POST(request: NextRequest) { const { email } = await request.json(); const result = await syvel.checkEmail(email);
if (result?.is_risky) { return NextResponse.json( { error: "Please use a professional email address." }, { status: 422 } ); } // continue with registration…}