alpinemail
v0.1.0
Published
GDPR-compliant email validation API - European alternative to ZeroBounce, NeverBounce
Maintainers
Readme
alpinemail
GDPR-compliant email validation API for Node.js. European alternative to ZeroBounce, NeverBounce.
Austrian company | Servers in Germany | Data never leaves EU
Features
- MX record validation
- SMTP deliverability check
- Disposable email detection (10k+ domains)
- AI fraud scoring (gibberish, keyboard walks)
- Role account detection (info@, support@, etc.)
- Catch-all detection
- Automatic retries with exponential backoff
- Full TypeScript support
- Zero dependencies
- Node.js 18+
Installation
npm install alpinemailQuick Start
import { validateEmail } from 'alpinemail';
const result = await validateEmail('[email protected]', {
apiKey: process.env.ALPINEMAIL_API_KEY,
});
console.log(result);
// {
// valid: true,
// email: '[email protected]',
// score: 0.95,
// disposable: false,
// risk: 'low',
// reason: 'valid',
// catchAll: false,
// roleAccount: false
// }Client Usage
For multiple validations, create a client instance:
import { AlpineMail } from 'alpinemail';
const client = new AlpineMail({
apiKey: process.env.ALPINEMAIL_API_KEY,
timeout: 15000, // optional, default 10000ms
retries: 3, // optional, default 2
});
// Basic validation
const result = await client.validate('[email protected]');
// With fraud detection context
const result = await client.validate('[email protected]', {
name: 'John Doe', // helps detect name/email mismatches
checks: ['basic', 'fraud'], // default
context: {}, // additional context
});
// Health check
const health = await client.healthCheck();
console.log(health.latency); // 42Error Handling
import {
AlpineMail,
AuthenticationError,
RateLimitError,
TimeoutError,
NetworkError,
ValidationError,
} from 'alpinemail';
const client = new AlpineMail({ apiKey: 'invalid' });
try {
await client.validate('[email protected]');
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof TimeoutError) {
console.error('Request timed out');
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
} else if (error instanceof ValidationError) {
console.error(`Invalid ${error.field}: ${error.message}`);
}
}Request Cancellation
const controller = new AbortController();
// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
await client.validate('[email protected]', {
signal: controller.signal,
});
} catch (error) {
if (error instanceof TimeoutError) {
console.error('Request was cancelled');
}
}Response Fields
| Field | Type | Description | |-------|------|-------------| | valid | boolean | Whether email is deliverable | | email | string | Normalized email address | | score | number | Quality score 0-1 (higher is better) | | disposable | boolean | Is temporary/disposable email | | risk | 'low' | 'medium' | 'high' | Overall risk level | | reason | string | Validation result reason | | catchAll | boolean | Domain accepts all emails | | roleAccount | boolean | Is role account (info@, etc.) | | mxRecords | string[] | MX records found (optional) |
Validation Reasons
| Reason | Description | |--------|-------------| | valid | Email is valid and deliverable | | invalid_format | Email format is invalid | | invalid_mx | No valid MX records found | | invalid_smtp | SMTP check failed | | disposable_domain | Known disposable email domain | | role_account | Generic role account detected | | gibberish | Random/gibberish local part | | keyboard_walk | Keyboard pattern detected (qwerty, etc.) | | catch_all | Domain accepts all emails | | unknown | Could not determine validity |
Configuration
| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | required | Your API key | | baseUrl | string | https://api.alpinemail.at | API base URL | | timeout | number | 10000 | Request timeout in ms | | retries | number | 2 | Retry attempts | | retryDelay | number | 1000 | Base retry delay in ms |
Security
Never commit API keys to version control.
Use environment variables:
export ALPINEMAIL_API_KEY=your-api-keyOr .env file with dotenv:
ALPINEMAIL_API_KEY=your-api-keyGet API Key
Sign up at alpinemail.at to get your API key.
Pricing: 100 free validations/month, then 0.01/request.
Support
- Email: [email protected]
- Issues: GitHub Issues
- Docs: alpinemail.at/docs
License
MIT © Sync Motion GmbH
