Skip to content

JavaScript / Node.js SDK

View as Markdown

Installation

Terminal window
npm install @syvel/js

Requirements: 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 automatically

Error 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 classHTTPWhen to fail open
SyvelTimeoutErrorAlways
SyvelRateLimitError429Always — check resetAt
SyvelAuthError401Fix your API key
SyvelForbiddenError403Check allowed origins
SyvelValidationError422Malformed 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…
}

Resources

Last updated: