Code Examples
Working code for the common integration points, with every example available in cURL, JavaScript/Node.js, Python, PHP, and Go where it applies — switch languages using the tabs on each code block rather than hunting through separate per-language pages.
A minimal client
No SDK is required for any of these — each is a small, dependency-free wrapper worth copying into a project as-is.
const BASE_URL = "https://api.emailriskradar.com";
class EmailRiskApiError extends Error {
constructor(code, message, status) {
super(message);
this.code = code;
this.status = status;
}
}
export function createClient(apiKey) {
async function request(path, options = {}) {
const res = await fetch(`${BASE_URL}${path}`, {
...options,
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
...options.headers,
},
});
const data = await res.json();
if (!res.ok) throw new EmailRiskApiError(data.error.code, data.error.message, res.status);
return data;
}
return {
checkEmail: (email, { mode = "standard", context = "generic" } = {}) =>
request("/v1/email/check", { method: "POST", body: JSON.stringify({ email, mode, context }) }),
submitBulk: (emails, { mode = "standard", context = "generic" } = {}) =>
request("/v1/email/bulk", { method: "POST", body: JSON.stringify({ emails, mode, context }) }),
getBulkStatus: (jobId) => request(`/v1/email/bulk/${jobId}`),
getBulkResults: (jobId, page = 1) => request(`/v1/email/bulk/${jobId}/results?page=${page}`),
};
}Using it
import { createClient } from "./email-risk-client.js";
const client = createClient(process.env.EMAIL_RISK_API_KEY);
const result = await client.checkEmail("user@example.com", { context: "signup" });
console.log(result.decision, result.risk.score);Bulk submission and polling
For anything beyond a quick script, prefer a webhook over polling — see Error Handling & Webhook Security for signature verification, and register the endpoint from the dashboard.
JOB_ID=$(curl -s https://api.emailriskradar.com/v1/email/bulk \
-H "Authorization: Bearer $EMAIL_RISK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"emails": ["a@example.com", "b@example.com"], "context": "crm"}' \
| jq -r '.job_id')
until [ "$(curl -s "https://api.emailriskradar.com/v1/email/bulk/$JOB_ID" \
-H "Authorization: Bearer $EMAIL_RISK_API_KEY" | jq -r '.status')" = "completed" ]; do
sleep 2
done
curl -s "https://api.emailriskradar.com/v1/email/bulk/$JOB_ID/results?page=1" \
-H "Authorization: Bearer $EMAIL_RISK_API_KEY" | jq '.data'Framework integration examples
The signup-time check pattern described in Checking at Signup Without Blocking the Flow, implemented in a few common frameworks:
"use server";
import { createClient } from "@/lib/email-risk-client";
export async function signupAction(formData: FormData) {
const email = formData.get("email") as string;
const client = createClient(process.env.EMAIL_RISK_API_KEY!);
const result = await client.checkEmail(email, { context: "signup" });
if (result.decision === "block") {
return { error: "This email address can't be used to sign up." };
}
// create the account...
}As always: never expose EMAIL_RISK_API_KEY to the browser, and for anything beyond a single-instance service, push background checks onto a real job queue instead of a bare goroutine or dangling promise — those don't survive the process restarting mid-check.