@deflectbot/deflect-node
v1.0.1
Published
Official Deflect Bot Protection SDK for Node.js
Readme
Deflect Node.js SDK
Official (early) Node.js SDK for the Deflect Bot Protection API.
Status: Experimental pre-release. API surface may change.
Installation
npm install @deflectbot/deflect-node
# or
yarn add @deflectbot/deflect-nodeQuick Start
import Deflect from '@deflectbot/deflect-node';
const deflect = new Deflect({
apiKey: process.env.DEFLECT_API_KEY!,
actionId: process.env.DEFLECT_ACTION_ID!
});
// Verify client-side token
const verdict = await deflect.getVerdict({
token: userSessionToken,
// optional identity enrichment
user_id: userId, // required for access control
email: userEmail, // optional
phone_number: userPhone // optional
});
if (verdict.verdict?.can_pass) {
// allow
} else {
// challenge / block
}API
new Deflect(options)
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| apiKey | string | Yes | Your Deflect API key |
| actionId | string | Yes | Action ID from dashboard |
| baseUrl | string | No | Override base URL (defaults to https://api.deflect.bot) |
| timeoutMs | number | No | Request timeout (default 4000) |
| fetchImplementation | Fetch | No | Custom fetch (Node <18 use undici) |
| maxRetries | number | No | Additional retry attempts for network/timeouts/5xx (default 2) |
getVerdict(request: DeflectVerdictRequest | string)
Returns a Promise<DeflectVerdictResponse> with structure mirroring the public docs.
The function accepts either:
- A
DeflectVerdictRequestobject with optional user identifiers - A string token
const verdict = await deflect.getVerdict({
token: userSessionToken,
user_id: 'user-123', // optional
email: '[email protected]', // optional
phone_number: '+15555551234' // optional
});
const verdict = await deflect.getVerdict(userSessionToken);DeflectVerdictRequest Interface:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| token | string | Yes | Session token from frontend SDK |
| user_id | string | No | Optional user identifier |
| email | string | No | Optional user email |
| phone_number | string | No | Optional user phone number |
Middleware has been intentionally omitted; integrate however you prefer (manually call getVerdict with the token supplied by your frontend layer).
getEmailIntelligence(email: string)
Returns a Promise<DeflectEmailIntelligenceResponse> with email validation and trust information.
const emailInfo = await deflect.getEmailIntelligence('[email protected]');
if (emailInfo.success && emailInfo.data?.is_valid && emailInfo.data?.is_trusted) {
// Email is valid and trusted
console.log('Trust score:', emailInfo.data.trust_score);
console.log('Normalized:', emailInfo.data.normalized_email);
}Response includes:
is_valid- Whether the email is validis_trusted- Whether the email is from a trusted domaintrust_score- Numeric trust scorehas_aliasing- Whether the email uses aliasingnormalized_email- Normalized email addressdomain- Email domain
getPhoneIntelligence(phone: string)
Returns a Promise<DeflectPhoneIntelligenceResponse> with phone number validation and risk information.
const phoneInfo = await deflect.getPhoneIntelligence('+15555551234');
if (phoneInfo.success && phoneInfo.data?.is_valid && !phoneInfo.data?.is_threat) {
// Phone is valid and not a threat
console.log('Carrier:', phoneInfo.data.carrier);
console.log('Risk score:', phoneInfo.data.risk_score);
}Response includes:
is_valid- Whether the phone number is valide164_format- Phone number in E.164 formatcountry_code- Country codecountry- Country ISO codecountry_name- Full country namenumber_type- Type of number (mobile, landline, etc.)line_type- Line type classificationcarrier- Phone carrier namecarrier_type- Type of carrierrisk_score- Numeric risk scoreis_disposable- Whether it's a disposable numberis_virtual- Whether it's a virtual numberis_threat- Whether it's flagged as a threatis_spam- Whether it's flagged as spamlast_updated- Last update timestamp
getIpIntelligence(ip: string)
Returns a Promise<DeflectIpIntelligenceResponse> with IP address intelligence and geolocation.
const ipInfo = await deflect.getIpIntelligence('8.8.8.8');
if (ipInfo.success && ipInfo.data && !ipInfo.data.is_vpn && !ipInfo.data.is_threat) {
// IP is not using VPN and not a threat
console.log('Location:', ipInfo.data.city, ipInfo.data.country);
console.log('ISP:', ipInfo.data.isp);
}Response includes:
is_vpn- Whether IP is using a VPNis_datacenter_proxy- Whether IP is a datacenter proxyis_residential_proxy- Whether IP is a residential proxyis_bogon- Whether IP is a bogon addressis_tor_node- Whether IP is a Tor exit nodeis_threat- Whether IP is flagged as a threatcity- City namepostal_code- Postal codecountry- Country ISO codecontinent- Continent codelatitude- Geographic latitudelongitude- Geographic longitudeasn_number- ASN numberasn_organization- ASN organization nameisp- Internet service provider name
Error Handling
Errors throw DeflectError with optional status and causeBody (API error body). Timeouts produce status 408. Network errors have status undefined.
Retries
The client retries instantly (no backoff) up to maxRetries additional times for:
- Network errors (thrown before a response)
- Timeouts (AbortError)
- 5xx HTTP responses It does not retry 4xx responses.
try {
await deflect.getVerdict(token);
} catch (e) {
if (e instanceof DeflectError) {
console.error('Deflect error', e.status, e.causeBody);
}
}Contributing
- Build:
npm run build - Dev watch:
npm run dev - Lint:
npm run lint - Test:
npm test
License
MIT
