Form Email Validation
Add real-time email validation to your web forms using Truelist Form API keys. Validate emails at the point of entry to prevent invalid addresses from entering your system.
Tip
This page documents the underlying API. For the no-code widget, see Form Validation Widget.
Getting started
- Go to your API Keys settings in the Truelist dashboard
- Under Form API keys, click Add key
- Give your key a name and optionally restrict it to specific domains
- Copy the key — it will only be shown once
Note
API endpoint
POST https://api.truelist.io/api/v1/form_verify Headers
| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer YOUR_FORM_API_KEY |
The Origin header is automatically sent by the browser and is used to enforce domain restrictions.
Request body
{
"email": "user@example.com"
} Responses
The form validation endpoint returns a simplified set of results designed for real-time form validation.
Success responses (200)
| Result | Description | Example |
|---|---|---|
valid | The email address is valid | { "result": "valid" } |
invalid | The email address is invalid. May include a suggested correction. | { "result": "invalid", "suggestion": "user@gmail.com" } |
risky | The email exists but may have deliverability issues (e.g. accept-all domain) | { "result": "risky" } |
unknown | The result could not be determined | { "result": "unknown" } |
Note
Error responses
| Status | Error | Description |
|---|---|---|
| 401 | invalid_api_key | The API key is missing or invalid |
| 403 | domain_not_allowed | The requesting domain is not in the key’s allowed domains list |
| 403 | https_required | The request must be made over HTTPS |
| 403 | origin_required | The Origin header is missing from the request |
| 422 | email_required | The email field is missing from the request body |
| 429 | rate_limited | Too many requests from this IP address |
Error responses have the format:
{
"error": "domain_not_allowed"
} Integration example
Add the following JavaScript to your form’s submit handler. Replace YOUR_FORM_API_KEY with your actual key.
const form = document.querySelector('#signup-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const email = form.querySelector('input[type="email"]').value;
const response = await fetch('https://api.truelist.io/api/v1/form_verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_FORM_API_KEY'
},
body: JSON.stringify({ email })
});
const data = await response.json();
if (data.error) {
console.error('Validation error:', data.error);
return;
}
if (data.result === 'invalid') {
if (data.suggestion) {
alert('Did you mean ' + data.suggestion + '?');
} else {
alert('Please enter a valid email address.');
}
return;
}
// Email is valid or risky — continue with form submission
form.submit();
}); Inline validation
You can also validate on blur (when the user leaves the email field) for faster feedback:
const emailInput = document.querySelector('input[type="email"]');
const errorEl = document.querySelector('#email-error');
emailInput.addEventListener('blur', async () => {
const email = emailInput.value;
if (!email) return;
const response = await fetch('https://api.truelist.io/api/v1/form_verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_FORM_API_KEY'
},
body: JSON.stringify({ email })
});
const data = await response.json();
if (data.result === 'invalid') {
errorEl.textContent = data.suggestion
? 'Did you mean ' + data.suggestion + '?'
: 'This email address appears to be invalid.';
errorEl.classList.remove('hidden');
} else {
errorEl.classList.add('hidden');
}
}); Credit usage
Form validations use the same credit system as other validations. Credits are charged for definitive results (valid / invalid) but not for uncertain results (unknown).
Security considerations
- Domain restrictions: Always configure allowed domains for production keys so they can only be used from your website.
- Per-IP rate limiting: Each form API key is automatically rate limited per client IP address. Even if a key were to be exposed, it cannot be used more than a few times per day from any single IP address. This prevents abuse without requiring any configuration on your part.
- HTTPS required: The endpoint requires HTTPS in production to protect API keys in transit.
- Disable unused keys: If a key is compromised, disable or regenerate it immediately from the dashboard.
Note
Domain pattern rules
When configuring allowed domains for a key, the following formats are supported:
| Pattern | Matches |
|---|---|
example.com | Only example.com |
*.example.com | www.example.com, app.example.com, and example.com itself |
localhost | localhost on any port (for development) |
Managing keys
From the API Keys settings page you can:
- Edit a key’s name, allowed domains, or enabled status
- Regenerate a key if it has been compromised (the old key stops working immediately)
- Delete a key you no longer need