@datacops/services-sdk
v1.0.2
Published
Official DataCops Services SDK — email identity lookup, risk scoring, and device-based relationship detection.
Downloads
27
Maintainers
Readme
@datacops/services-sdk
The official DataCops Services SDK for Node.js and browser environments.
Look up email identities captured by the DataCops tracking script, retrieve full email risk analysis, and discover related email addresses that share the same device fingerprint — all in a single API call.
Table of Contents
- Requirements
- Installation
- Quick Start
- Configuration
- Methods
- Response Reference
- Error Handling
- Cancelling Requests
- TypeScript
- Publishing
- Security
Requirements
| Runtime | Minimum version |
|-----------------|-----------------|
| Node.js | 18.0.0 |
| Browser | Any modern browser with fetch and AbortController |
The SDK has zero runtime dependencies. It uses the native fetch API available in Node 18+ and all modern browsers.
Installation
# npm
npm install @datacops/services-sdk
# yarn
yarn add @datacops/services-sdk
# pnpm
pnpm add @datacops/services-sdkQuick Start
import { DCServiceSdk } from "@datacops/services-sdk";
const sdk = new DCServiceSdk({ apiKey: "dcp_your_private_key_here" });
const result = await sdk.checkEmail("[email protected]");
console.log(result.emailInfo?.risk_label); // "low" | "medium" | "high" | "critical"
console.log(result.emailInfo?.action); // "ALLOW" | "CHALLENGE" | "BLOCK"
console.log(result.related_email_count); // 2
console.log(result.related_emails); // ["[email protected]", "[email protected]"]Note: The SDK ships as both ESM (
import) and CommonJS (require). Both module systems are fully supported.
// CommonJS
const { DCServiceSdk } = require("@datacops/services-sdk");Configuration
Pass options to the DCServiceSdk constructor:
const sdk = new DCServiceSdk({
apiKey: "dcp_your_private_key_here", // required
baseUrl: "https://api.joindatacops.com", // optional, this is the default
timeout: 10_000, // optional, milliseconds — default: 10 000 (10 s)
});| Option | Type | Required | Default | Description |
|-----------|----------|----------|---------------------------------------|----------------------------------------------------|
| apiKey | string | Yes | — | Your DataCops private API key (starts dcp_). |
| baseUrl | string | No | https://api.joindatacops.com | Override the API base URL (useful for self-hosted or staging). |
| timeout | number | No | 10000 | Milliseconds before the SDK throws DCServiceTimeoutError. |
Methods
checkEmail
sdk.checkEmail(email: string, options?: RequestOptions): Promise<EmailCheckResult>Looks up an email address in the DataCops identity store. Returns the most recent identity record associated with the email together with:
- A full email risk analysis (
emailInfo) - A list of related emails seen on the same device(s)
Parameters
| Parameter | Type | Description |
|------------------|-------------------|----------------------------------------------------|
| email | string | The email address to look up. |
| options.signal | AbortSignal | Optional. Cancel the request at any time. See Cancelling Requests. |
Example
const result = await sdk.checkEmail("[email protected]");
// Email risk
console.log(result.emailInfo?.risk_score); // 0–100
console.log(result.emailInfo?.risk_label); // "low" | "medium" | "high" | "critical"
console.log(result.emailInfo?.action); // "ALLOW" | "CHALLENGE" | "BLOCK"
console.log(result.emailInfo?.reasons); // ["free_provider", "young_domain"]
console.log(result.emailInfo?.tags); // ["gmail", "new_account"]
// Fraud signals
const fraud = result.emailInfo?.fraud_signals;
console.log(fraud?.disposable_domain); // false
console.log(fraud?.domain_trust_score); // 85
console.log(fraud?.identity_flags.bulk_pattern); // false
// Digital footprint
const footprint = result.emailInfo?.digital_footprint;
console.log(footprint?.likely_real_person); // true
console.log(footprint?.presence_score); // 72
// Related emails on the same device
console.log(result.related_email_count); // 3
console.log(result.related_emails); // ["[email protected]", "[email protected]"]
// Identity metadata
console.log(result.normalized_email); // "[email protected]" (plus-stripped)
console.log(result.sessionId); // DataCops session ID
console.log(result.pageUrl); // URL where identity was captured
console.log(result.deviceFingerprint?.hash); // device hashResponse Reference
checkEmail resolves to an EmailCheckResult object:
interface EmailCheckResult {
email: string;
normalized_email: string | null;
sessionId: string;
userId: string | null;
pageUrl: string | null;
userAgent: string | null;
deviceFingerprint: {
hash: string;
short: string;
confidence: number; // 0–100
version: string;
} | null;
emailInfo: {
status: "ok";
email: string;
normalized_email: string;
domain: string;
risk_score: number; // 0 = no risk, 100 = critical risk
risk_label: "low" | "medium" | "high" | "critical";
action: "ALLOW" | "CHALLENGE" | "BLOCK";
reasons: string[]; // human-readable risk reasons
tags: string[]; // categorical tags (e.g. "disposable", "free_provider")
digital_footprint: {
presence_score: number;
has_public_profile: boolean;
display_name: string | null;
profile_url: string | null;
likely_real_person: boolean;
};
fraud_signals: {
disposable_domain: boolean;
domain_trust_score: number;
infrastructure_shared: boolean;
identity_flags: {
gibberish_username: boolean;
bulk_pattern: boolean;
plus_addressing: boolean;
free_provider: boolean;
};
domain_maturity: {
age_days: number | null;
registered_at: string | null;
young_domain: boolean;
};
};
suggestion: string | null; // e.g. "Consider requiring email verification"
} | null;
identifiedAt: string; // ISO 8601 timestamp
related_email_count: number;
related_emails: string[];
}Error Handling
The SDK never swallows errors silently. Every failure surfaces as a typed error class that you can instanceof-check:
Error Types
| Class | When thrown |
|-----------------------------|-------------------------------------------------------------------|
| DCServiceValidationError | Bad arguments (missing apiKey, invalid email format, etc.). These are programming mistakes — do not retry. |
| DCServiceError | Server responded with a non-2xx status code. Check err.statusCode and err.message. |
| DCServiceAbortError | The request was cancelled via an AbortSignal you supplied. |
| DCServiceTimeoutError | The SDK's own timeout fired. Check err.timeoutMs. |
| DCServiceNetworkError | Low-level network failure (DNS error, connection refused, etc.). |
All error classes extend the native Error and carry a descriptive .message.
Handling Every Case
import {
DCServiceSdk,
DCServiceError,
DCServiceAbortError,
DCServiceTimeoutError,
DCServiceNetworkError,
DCServiceValidationError,
} from "@datacops/services-sdk";
const sdk = new DCServiceSdk({ apiKey: "dcp_xxx" });
try {
const result = await sdk.checkEmail("[email protected]");
console.log(result);
} catch (err) {
if (err instanceof DCServiceValidationError) {
// Fix the code — bad arguments were passed
console.error("Invalid input:", err.message);
} else if (err instanceof DCServiceAbortError) {
// The caller cancelled the request — usually intentional, not an error
console.info("Request cancelled");
} else if (err instanceof DCServiceTimeoutError) {
// Server took too long — consider retrying with back-off
console.warn(`Timed out after ${err.timeoutMs}ms`);
} else if (err instanceof DCServiceError) {
// HTTP error from the server
if (err.statusCode === 401) {
console.error("Invalid API key — check your dcp_ key");
} else if (err.statusCode === 404) {
console.info("Email not found in the identity store");
} else if (err.statusCode === 429) {
console.warn("Rate limited — slow down");
} else {
console.error(`Server error ${err.statusCode}: ${err.message}`);
}
} else if (err instanceof DCServiceNetworkError) {
// Network layer failure — safe to retry
console.error("Network error:", err.message);
}
}Cancelling Requests
Pass an AbortSignal to cancel an in-flight request before it completes. This is useful for implementing per-request timeouts, React cleanup effects, or user-triggered cancellations.
Cancel after a deadline
const controller = new AbortController();
// Cancel after 3 seconds
setTimeout(() => controller.abort(), 3_000);
try {
const result = await sdk.checkEmail("[email protected]", {
signal: controller.signal,
});
} catch (err) {
if (err instanceof DCServiceAbortError) {
console.info("Cancelled by the caller");
}
}Cancel on React component unmount
useEffect(() => {
const controller = new AbortController();
sdk.checkEmail(email, { signal: controller.signal })
.then(setResult)
.catch((err) => {
if (!(err instanceof DCServiceAbortError)) {
setError(err);
}
});
return () => controller.abort(); // cleanup on unmount
}, [email]);Native timeout shorthand (Node 17+)
const result = await sdk.checkEmail("[email protected]", {
signal: AbortSignal.timeout(5_000), // cancel after 5 s, no controller needed
});Note: The SDK also applies its own internal timeout (default 10 s, configurable via the
timeoutconstructor option). The first signal to fire wins — whether it's yours or the SDK's.
TypeScript
The SDK is written in TypeScript and ships full type definitions. No @types/ package is needed.
import type {
EmailCheckResult,
EmailInfo,
RiskAction,
RiskLabel,
RequestOptions,
DCServiceSdkOptions,
} from "@datacops/services-sdk";
function handleRisk(action: RiskAction): void {
if (action === "BLOCK") {
// ...
}
}All public types are re-exported from the package root.
Publishing
The prepublishOnly script runs automatically on npm publish and:
- Cleans the
dist/folder - Type-checks the source (
tsc --noEmit) - Builds ESM + CJS bundles with declaration files (
tsup)
# Bump the version first
npm version patch # or minor / major
# Publish to npm (runs build automatically)
npm publish --access publicTo publish to a private registry, set publishConfig in package.json:
"publishConfig": {
"registry": "https://your-private-registry.com"
}Local development build
npm install
npm run build # one-off build → dist/
npm run build:watch # rebuild on every file change
npm run typecheck # type-check without emittingSecurity
- Your API key is never logged or stored by the SDK. It is sent only as the
x-dc-keyHTTP header on each request, over HTTPS. - Keep your
dcp_key secret. Do not commit it to source control or expose it in client-side browser bundles. - For server-side use in Node.js, load the key from an environment variable:
const sdk = new DCServiceSdk({ apiKey: process.env.DATACOPS_API_KEY! }); - Rotate your key immediately if it is ever exposed. You can generate a new key from the DataCops dashboard at any time.
License
MIT © DataCops
