Protect Your Signup Flow
SignGuard is a single API call you put before your database write to block free-trial abuse, burner emails, and bots. It takes 3 lines of code and evaluates the email using a fast in-memory lookup.
Authentication & Base URL
All API requests must be made over HTTPS. The base URL for all endpoints is:
https://api.signguard.coAuthenticate your API requests by including your API key in the Authorization header as a Bearer token. You can generate an API key from the Dashboard.
Authorization: Bearer dsk_live_your_api_key_hereQuickstart: API Request
Get your API key from the dashboard and pass it as a Bearer token. We recommend using mode="fast" on signup forms to skip the physical SMTP ping and keep latency low.
How it works:
"block", interrupt the flow and prompt for a work email."allow", safely generate their user records and award trial credits.// Example usage in Javascript/Typescript
const response = await fetch('https://api.signguard.co/v1/check', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: 'spammer@tempmail.xyz', mode: 'fast' }),
});
const result = await response.json();
console.log(result.decision); // "block"
console.log(result.reasons); // ["disposable_email"]Python SDK & Node.js HTTP Integration
Our open-source Python SDK automatically falls back to local offline evaluation if the API is unreachable. For Node.js and other environments, we recommend a fail-open try/catch wrapper.
Python SDK (Built-in Offline Fallback)
# 1. Install package
pip install disposable-email-score[api]
# 2. Set environment variable
export SIGNGUARD_API_KEY="dsk_live_your_key_here"
# 3. Perform check in Python (falls back to local offline engine if API is unreachable)
from disposable_email_score import configure, evaluate_email
configure() # Reads SIGNGUARD_API_KEY from environment
result = evaluate_email("user@tempmail.xyz")
if result.decision == "block":
print("❌ Blocked disposable email!")Node.js / TypeScript (Fail-Open HTTP API)
Use native fetch() with a 3-second timeout. If the request fails or times out, fail-open to allow the signup.
async function checkEmail(email) {
try {
const response = await fetch("https://api.signguard.co/v1/check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SIGNGUARD_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ email, mode: "fast" }),
signal: AbortSignal.timeout(3000) // 3s timeout
});
if (!response.ok) throw new Error(`API returned status ${response.status}`);
const data = await response.json();
return data.decision; // "allow", "review", or "block"
} catch (err) {
console.warn("SignGuard API unreachable, failing open:", err.message);
return "allow"; // Fail-open: allow signup on network timeout or error
}
}Integration Recipes
Copy and paste these snippets into your favorite framework.
Next.js App Router (Server Action)
"use server";
export async function signUpUser(formData: FormData) {
const email = formData.get("email");
// 1. Check risk
const response = await fetch('https://api.signguard.co/v1/check', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SIGNGUARD_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, mode: 'fast' }),
});
const check = await response.json();
if (check.decision === "block") {
return { error: "Please use a legitimate email address." };
}
// 2. Safe to create user in DB
await db.users.create({ email });
}Supabase / Clerk Webhook
app.post("/webhook/user.created", async (req, res) => {
const email = req.body.data.email_address;
const response = await fetch('https://api.signguard.co/v1/check', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SIGNGUARD_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, mode: 'fast' }),
});
const check = await response.json();
if (check.decision === "block") {
// Optionally delete the user instantly if they bypassed the frontend
await supabase.auth.admin.deleteUser(req.body.data.id);
return res.status(403).send("User deleted - fraud detected.");
}
res.send("OK");
});Response Schema & Decisions
Our API returns clear decisions and rich signals so you never have to guess why a user was blocked.
{
"email": "spammer@gmaiil.com",
"decision": "block", // "allow", "review", or "block"
"score": 1.0, // 0.0 (safe) to 1.0 (fraudulent)
"thresholds": {
"allow": 0.3,
"block": 0.7
},
"is_disposable": false,
"has_mx_records": true,
"mailbox_exists": false,
"domain_age_days": 2,
"is_catch_all": false,
"signals": {
"typosquatting": 0.6,
"role_account": 0.2
},
"reasons": [
"typosquatting_detected:gmail.com",
"role_account_detected"
]
}Error Reference
SignGuard uses conventional HTTP response codes to indicate the success or failure of an API request.
| Status | Error Type | Description |
|---|---|---|
| 400 | bad_request | Invalid email format or request body. |
| 401 | unauthorized | Missing or invalid API key. |
| 429 | rate_limit_exceeded | Per-minute rate limit or monthly quota exceeded. |
| 500 | internal_error | Something went wrong on our end. Fail open! |
Rate Limits & Quotas
We enforce two types of limits to protect our infrastructure and your billing plan:
- Per-minute:600 requests/minute (Sliding window) for Free, Starter, and Pro plans. Enterprise plan allows 3000+ requests/minute.
- Monthly Quota:Based on your plan (Free: 200, Starter: 20K, Pro: 100K, Enterprise: 250K+).
If you exceed these limits, the API will return a 429 Too Many Requests error. We strongly recommend configuring your application to fail open (allow the signup) if a 429 occurs.
Idempotency & Safe Retries
SignGuard automatically detects exact duplicate API requests using a built-in idempotency engine.
How it works
If your application accidentally sends the exact same payload multiple times in a row (e.g., a user double-clicking a submit button, or a network timeout triggering an automatic retry), we serve the response from cache instantly.
Zero Cost for Duplicates: Cached idempotent responses do not charge your monthly quota and do not increment your usage counter.
Production Checklist
Before going live with real signups, ensure you've handled these edge cases to guarantee high availability.
1. Handle All Decisions
Don't blindly trust or block. Map the 3 decision states to UX:
"allow": Let them through immediately."review": (Optional) Challenge with an OTP, CAPTCHA, or push to manual review. Treat as"allow"if you prefer low friction."block": Hard stop. Reject the signup and ask for a work email.
2. Fail Open on Errors (Timeouts & 5xx)
If our API times out or returns a 5xx error, wrap it in a
try/catchand allow the signup. Do not block a legitimate customer because of a network flake.3. Respect Quota Limits (429 / 401)
If you hit your Free quota limit, the API returns a
429 Too Many Requests. You should fail open (allow the user) and upgrade your plan in the dashboard.4. False Positives? Use the Allowlist
If a real customer is accidentally blocked by a strict rule, go to the Dashboard → API Keys → Settings and add their domain to the Custom Allowlist. It applies instantly.
Estimated Cost Avoided (Dashboard ROI)
The dashboard multiplies blocked risky signups by your cost per fake signup. Default is $0.50 (a rough estimate for free-trial or LLM-credit costs). Change it under the Signup Protection card to match your actual infrastructure cost. This is an internal estimate for ROI tracking, not a real billing number.
Modes: fast vs deep
The mode parameter controls how aggressively we verify the email. Default is deep if omitted.
mode: "fast" (Recommended)
Best for inline signup forms. Completes quickly with no external SMTP round-trip.
- Disposable/Burner blocklists
- Custom Allow/Block lists
- DNS MX Record check
- Domain Age verification
- Typosquatting engine
mode: "deep"
Best for background jobs or async cleaning. Completes in 1-3s.
- Everything in "fast" mode
- Active SMTP mailbox ping
- Catch-all domain detection
Advanced: Batch Endpoint (/v1/check/batch)
For cleaning historical users from your database, you can pass up to 100 emails at once.
POST /v1/check/batch
{
"emails": [
"user1@gmail.com",
"spammer@tempmail.com"
],
"mode": "fast"
}Email Finder Endpoint (/v1/find)
Find anyone's verified work email address from their name and company domain. Generates 15 permutation patterns and performs real-time SMTP verification against the domain's mail server.
curl -X POST https://api.signguard.co/v1/find \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "John",
"last_name": "Doe",
"domain": "stripe.com"
}'
# NOTE: This endpoint charges 5 request credits per call due to heavy SMTP validation.
# Response
{
"status": "found", // "found", "not_found", "catch_all", or "error"
"email": "john.doe@stripe.com",
"message": "Verified email found.",
"permutations_tested": 15
}Advanced: MCP Server for AI Agents
For developers orchestrating Claude Desktop or Cursor, we provide a native Model Context Protocol (MCP) server so your agents can validate emails natively without writing HTTP wrappers.
"mcpServers": {
"signguard": {
"command": "uvx",
"args": ["signguard-mcp-server"],
"env": {
"SIGNGUARD_API_KEY": "YOUR_KEY"
}
}
}