Angular SDK
Angular service and module for seamless integration in Angular applications
Installation
npm (Recommended)
Install the Angular SDK using npm, the Node.js package manager. This is the recommended installation method for most Angular projects.
npm install @keverdjs/fraud-sdk-angularyarn
Alternatively, install using Yarn if you prefer it over npm.
yarn add @keverdjs/fraud-sdk-angularPeer Dependencies
The Angular SDK requires Angular 15.0 or higher and RxJS 7.0 or higher. These should already be installed in your Angular project, but if not, install them:
npm install @angular/core@^15.0.0 rxjs@^7.0.0
# or
yarn add @angular/core@^15.0.0 rxjs@^7.0.0Note: The SDK uses Angular's dependency injection system and RxJS Observables for reactive data access. The SDK is provided as a singleton service using Angular's providedIn: 'root' pattern, making it available throughout your application.
Quick Start
1. Import Module
Import the KeverdModule in your root module (app.module.ts) and configure it using the forRoot() method. This method follows Angular's module configuration pattern and provides the SDK configuration to the dependency injection system.
Important: The endpoint must use HTTPS. The SDK will throw an error if you provide an HTTP URL. The default API endpoint is https://api.keverd.com.
For Angular Standalone Components: If you're using Angular standalone components (Angular 14+), you can import the KeverdService directly and call init() manually, or use Angular's APP_INITIALIZER to initialize the SDK at application startup.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { KeverdModule } from '@keverdjs/fraud-sdk-angular';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
KeverdModule.forRoot({
apiKey: environment.keverdApiKey, // Use environment variables
endpoint: 'https://api.keverd.com', // Optional: defaults to https://api.keverd.com
debug: !environment.production, // Enable debug in dev only
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}Dependency Injection: The KeverdModule.forRoot() method configures the SDK and provides it to Angular's dependency injection system. The KeverdService is provided as a singleton service using providedIn: 'root', making it available throughout your application.
Initialization: The SDK is initialized automatically when the module is loaded. The initialization is synchronous and non-blocking, but you should wait for the SDK to be ready before making API calls (use isReady() to check).
2. Use Service in Components
Inject the KeverdService into your components using Angular's dependency injection. The service provides an RxJS Observable-based API for accessing visitor data and risk assessment. All methods return Observables, allowing you to use RxJS operators for reactive data handling.
Performance: Data collection typically completes in under 50ms. The total time (including network request) is typically under 200ms (p99 latency). The service uses RxJS Observables for efficient reactive data handling.
import { Component, OnInit } from '@angular/core';
import { KeverdService } from '@keverdjs/fraud-sdk-angular';
import type { KeverdVisitorData } from '@keverdjs/fraud-sdk-angular';
@Component({
selector: 'app-root',
template: \`
<div *ngIf="loading">Loading risk assessment...</div>
<div *ngIf="error">
<p>Error: {{ error.message }}</p>
<button (click)="checkRisk()">Retry</button>
</div>
<div *ngIf="data && !loading">
<p>Risk Score: {{ data.riskScore }}/100</p>
<p>Action: {{ data.action }}</p>
<p>Reasons: {{ data.reasons.join(', ') }}</p>
<button (click)="checkRisk()">Reload data</button>
</div>
\`
})
export class AppComponent implements OnInit {
data: KeverdVisitorData | null = null;
loading = false;
error: any = null;
constructor(private keverd: KeverdService) {}
ngOnInit() {
this.checkRisk();
}
checkRisk() {
this.loading = true;
this.error = null;
this.keverd.getVisitorData({
extendedResult: true
}).subscribe({
next: (data) => {
this.data = data;
this.loading = false;
},
error: (err) => {
this.error = err;
this.loading = false;
}
});
}
}API Reference
KeverdModule
Angular module that provides the Keverd SDK service to your application. The module follows Angular's module configuration pattern and uses the forRoot() method to configure the SDK with your API key and settings.
KeverdModule.forRoot(config: KeverdConfig): ModuleWithProviders<KeverdModule>
Static method that configures the module with SDK settings. This method should be called in your root module's imports array. The method returns a ModuleWithProviders object that includes the module and its providers.
Parameters:
config(KeverdConfig): Configuration object for SDK initialization. SeeKeverdConfigbelow for details.
Returns: ModuleWithProviders<KeverdModule> - Module configuration object that includes the module and its providers.
Dependency Injection: The method provides the KeverdService and configuration to Angular's dependency injection system. The service is provided as a singleton using providedIn: 'root'.
Initialization: The SDK is initialized automatically when the service is first injected. The initialization is synchronous and non-blocking.
KeverdConfig
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
| apiKey | string | Yes | — | API key for authenticating requests to the Keverd API. Obtain your API key from the API Keys page in the dashboard. Keep your API key secure and never commit it to version control. Use environment variables in production. |
| endpoint | string | No | 'https://api.keverd.com' | Base URL for the fingerprint API endpoint. Must start with "https://" (HTTP is not allowed for security). Only change this if you're using a custom endpoint or testing environment. |
| debug | boolean | No | false | Enable debug logging. When true, the SDK will log debug information to the browser console. Set to true during development and false in production. |
| userId | string | No | undefined | User identifier (string). This is not hashed and is sent as-is to the API. If not provided or empty, the backend will auto-generate an identifier from the device fingerprint. Use this to associate fingerprint requests with specific users in your system. |
Usage Example
KeverdModule.forRoot({
apiKey: environment.keverdApiKey,
endpoint: 'https://api.keverd.com',
debug: !environment.production
})KeverdService
Angular injectable service for accessing visitor data and risk assessment. The service is provided as a singleton using providedIn: 'root', making it available throughout your application. All methods return RxJS Observables for reactive data handling.
init(config: KeverdConfig): void
Initialize the SDK with configuration. This method is optional if you're using KeverdModule.forRoot(), as the SDK will be initialized automatically via dependency injection. Use this method if you need to initialize the SDK manually or change the configuration at runtime.
Parameters:
config(KeverdConfig): Configuration object for SDK initialization. TheapiKeyis required.
Returns: void
Throws: Throws an Error if apiKey is not provided or if the SDK is already initialized (subsequent calls are ignored).
getVisitorData(options?: KeverdVisitorDataOptions): Observable<KeverdVisitorData>
Get visitor data and risk assessment. This is the main method for fraud detection. The method collects device information, behavioral data, and session information, then sends it to the Keverd API to receive a risk assessment. The method returns an RxJS Observable that emits the visitor data when the request completes.
Parameters:
options(optional): Configuration options for the request- -
extendedResult(boolean, optional): Include extended result data in the response. Default:false - -
ignoreCache(boolean, optional): Ignore cached results and force a fresh API call. Default:false - -
tag(string, optional): Tag for request tracking (e.g., 'sandbox' for sandbox requests)
Returns: Observable<KeverdVisitorData> - An RxJS Observable that emits a single KeverdVisitorData object when the request completes successfully.
RxJS Observable: The method returns an Observable, allowing you to use RxJS operators (e.g., map, catchError, retry) for reactive data handling and error management.
Performance: Data collection typically completes in under 50ms. The total time (including network request) is typically under 200ms (p99 latency). Network timeouts are set to 30 seconds for connection, read, and write operations.
Error Handling: If an error occurs during data collection or API submission, the Observable will emit an error. You should handle errors using the error callback in subscribe() or using RxJS operators like catchError.
Throws: The Observable will error if the SDK is not initialized (call init() first or use KeverdModule.forRoot()) or if the API request fails (network errors, invalid API key, server errors, etc.).
isReady(): boolean
Check if the SDK is initialized and ready to use. This method returns true if the SDK has been initialized and is ready to make API calls, and false otherwise.
Parameters: None
Returns: boolean - true if the SDK is initialized and ready, false otherwise.
Use Cases: Use this method to check if the SDK is ready before calling getVisitorData(). This is especially useful if you're initializing the SDK manually or if you need to wait for initialization to complete.
destroy(): void
Destroy the SDK instance and stop all data collection. This method stops behavioral data collection, clears the internal configuration, and resets the initialization state. After calling this method, you must call init() again before using the SDK.
Parameters: None
Returns: void
Use Cases: Call this method when you want to stop all SDK activity, such as when a user logs out, when switching to a different API key, or when cleaning up resources. After destroying, you can reinitialize with a new configuration.
getConfig(): KeverdConfig | null
Get the current SDK configuration. This method returns the configuration object that was used to initialize the SDK, or null if the SDK is not initialized.
Parameters: None
Returns: KeverdConfig | null - The current configuration object, or null if the SDK is not initialized.
Note: The returned configuration object is a copy of the internal configuration. Modifying it will not affect the SDK's behavior.
KeverdVisitorData
The visitor data object returned by the SDK. This object contains the risk assessment, action recommendation, and session information. When returned from getVisitorData(), this object is emitted by the RxJS Observable.
KeverdVisitorData Interface
interface KeverdVisitorData {
visitorId: string; // Unique visitor identifier (UUID)
riskScore: number; // Risk score (0-100, where 100 is highest risk)
score: number; // Risk score as float (0.0-1.0, normalized)
action: 'allow' | 'soft_challenge' | 'hard_challenge' | 'block';
reasons: string[]; // Array of risk reasons
sessionId: string; // Session identifier (UUID)
requestId: string; // Request identifier (UUID, same as sessionId)
simSwapEngine?: { // SIM swap detection results (null for web SDKs)
risk: number;
flags: {
sim_changed?: boolean;
device_changed?: boolean;
behavior_anomaly?: boolean;
time_anomaly?: boolean;
velocity_anomaly?: boolean;
};
};
confidence?: number; // Confidence score (inverse of risk, 0.0-1.0)
}visitorId: Unique visitor identifier in UUID format. This identifier is consistent across sessions for the same device/browser.
riskScore: Risk score as an integer from 0 (lowest risk) to 100 (highest risk). Use this score to make security decisions in your application.
score: Normalized risk score as a float between 0.0 (lowest risk) and 1.0 (highest risk). This is equal to riskScore / 100.
action: Recommended action based on the risk score. Possible values: 'allow', 'soft_challenge', 'hard_challenge', or 'block'.
reasons: Array of strings explaining why the risk score was assigned. Each string describes a specific risk factor.
sessionId: Unique session identifier in UUID format. This identifier is generated client-side and is consistent across requests within the same browser session.
requestId: Unique request identifier in UUID format. This is the same as sessionId and is included for backward compatibility.
simSwapEngine: SIM swap detection data. This field is always null or undefined for web SDKs, as SIM card information is only available on mobile devices.
confidence: Confidence score as a float between 0.0 and 1.0. This is the inverse of the risk score (confidence = 1.0 - score). Higher values indicate higher confidence in the assessment.
Data Collection
The Angular SDK collects the same types of data as the Vanilla JavaScript SDK: device information, session information, and behavioral data. All sensitive identifiers are hashed client-side before transmission to ensure privacy and compliance with data protection regulations. No personally identifiable information (PII) is collected or transmitted in plain text.
Device Information
Collected automatically by the SDK. Includes device fingerprint, screen dimensions, timezone, locale, and hardware information. All sensitive data is hashed using SHA-256 before transmission.
Session Information
Tracks session and installation data. Session data is persisted in localStorage and is consistent across page reloads within the same browser session.
Behavioral Data
Collected passively as users interact with your application. The collector tracks mouse movements, keyboard input, touch gestures, and scroll events. Data collection starts automatically when the SDK is initialized and stops when destroy() is called.
Privacy: Behavioral data is aggregated and anonymized. Individual keystrokes or mouse movements are not transmitted; only statistical summaries are sent to the API.
Hashing and Privacy
All sensitive identifiers are hashed using SHA-256 before transmission. The SDK handles all hashing operations internally. This approach ensures compliance with GDPR, CCPA, and other data protection regulations.
Complete Example
Here's a complete example showing how to integrate the Angular SDK into an Angular application. This example demonstrates module setup, service injection, risk assessment, and error handling.
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { KeverdModule } from '@keverdjs/fraud-sdk-angular';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
KeverdModule.forRoot({
apiKey: 'your-api-key-here',
endpoint: 'https://api.keverd.com',
debug: false,
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { KeverdService } from '@keverdjs/fraud-sdk-angular';
import type { KeverdVisitorData } from '@keverdjs/fraud-sdk-angular';
@Component({
selector: 'app-root',
template: \`
<div>
<h1>Risk Assessment</h1>
<div *ngIf="loading">Loading risk assessment...</div>
<div *ngIf="error">
<p>Error: {{ error.message }}</p>
<button (click)="checkRisk()">Retry</button>
</div>
<div *ngIf="data && !loading">
<p>Risk Score: {{ data.riskScore }}/100</p>
<p>Action: {{ data.action }}</p>
<p>Reasons: {{ data.reasons.join(', ') }}</p>
<p>Risk Level: {{ getRiskLevel() }}</p>
<button (click)="checkRisk()">Refresh</button>
</div>
<div *ngIf="!data && !loading">
<button (click)="checkRisk()">Check Risk</button>
</div>
</div>
\`
})
export class AppComponent implements OnInit {
data: KeverdVisitorData | null = null;
loading = false;
error: any = null;
constructor(private keverd: KeverdService) {}
ngOnInit() {
this.checkRisk();
}
checkRisk() {
this.loading = true;
this.error = null;
this.keverd.getVisitorData({
extendedResult: true,
}).subscribe({
next: (data) => {
this.data = data;
this.loading = false;
},
error: (err) => {
this.error = err;
this.loading = false;
}
});
}
getRiskLevel(): string {
if (!this.data) return 'unknown';
if (this.data.riskScore >= 70) return 'high';
if (this.data.riskScore >= 30) return 'medium';
return 'low';
}
}RxJS Observable Usage
The Angular SDK uses RxJS Observables for reactive data access. You can use all RxJS operators to transform, filter, retry, and handle errors in your data streams. This makes it easy to integrate with Angular's reactive patterns and other RxJS-based libraries.
The Angular SDK uses RxJS Observables for reactive data access. You can use all RxJS operators:
import { map, catchError, retry } from 'rxjs/operators';
import { of } from 'rxjs';
this.keverd.getVisitorData()
.pipe(
map(data => {
// Transform data
return {
...data,
riskLevel: data.riskScore >= 70 ? 'high' : 'low'
};
}),
retry(3), // Retry up to 3 times on error
catchError(error => {
console.error('Keverd error:', error);
return of(null); // Return null on error
})
)
.subscribe({
next: (data) => {
if (data) {
this.data = data;
}
}
});Error Handling
The Angular SDK handles errors gracefully and provides them through RxJS Observable error emissions. Here's how to handle different error scenarios using RxJS operators:
Network Errors
Network errors occur when the device cannot connect to the API or when the request times out. The SDK uses 30-second timeouts for connection, read, and write operations.
import { catchError, retry, throwError } from 'rxjs';
import { of } from 'rxjs';
this.keverd.getVisitorData()
.pipe(
retry({
count: 3,
delay: (error, retryCount) => {
if (error.message.includes('timeout') || error.message.includes('Timeout')) {
// Retry with exponential backoff
return timer(retryCount * 1000);
}
return throwError(() => error);
}
}),
catchError((error) => {
if (error.message.includes('network') || error.message.includes('Network')) {
console.error('Network error:', error.message);
showNetworkError();
}
return throwError(() => error);
})
)
.subscribe({
next: (data) => this.data = data,
error: (err) => this.error = err
});API Errors
API errors occur when the server returns an error status code (4xx or 5xx). Common causes include invalid API keys, rate limiting, or server errors.
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
this.keverd.getVisitorData()
.pipe(
catchError((error) => {
if (error.code === 'HTTP_401' || error.message.includes('Unauthorized')) {
// Invalid API key
console.error('Invalid API key. Please check your configuration.');
showConfigurationError();
} else if (error.code === 'HTTP_429' || error.message.includes('rate limit')) {
// Rate limit exceeded
console.warn('Rate limit exceeded. Please retry after some time.');
showRateLimitError();
} else if (error.code?.startsWith('HTTP_5')) {
// Server errors - retry with backoff
console.error('Server error:', error.message);
return this.keverd.getVisitorData().pipe(
retry({ count: 3, delay: 1000 })
);
}
return throwError(() => error);
})
)
.subscribe({
next: (data) => this.data = data,
error: (err) => this.error = err
});SDK Not Initialized Errors
These errors occur when you try to use the SDK before it's initialized or when the module hasn't been configured.
this.keverd.getVisitorData()
.pipe(
catchError((error) => {
if (error.code === 'SDK_NOT_INITIALIZED') {
// SDK not initialized - initialize and retry
console.warn('SDK not initialized, initializing...');
this.keverd.init({
apiKey: environment.keverdApiKey,
endpoint: 'https://api.keverd.com'
});
// Retry after initialization
return this.keverd.getVisitorData();
}
return throwError(() => error);
})
)
.subscribe({
next: (data) => this.data = data,
error: (err) => this.error = err
});Best Practices for Error Handling
- Use RxJS operators: Use RxJS operators like
catchError,retry, andretryWhento handle errors reactively. - Implement retry logic: For transient errors (network timeouts, server errors), implement retry logic with exponential backoff using
retryorretryWhenoperators. - Fail gracefully: Decide on a fail-open or fail-closed strategy. Fail-open allows access when the SDK fails, while fail-closed blocks access. Choose based on your security requirements.
- Log errors: Log errors to your error tracking service (e.g., Sentry, LogRocket) for debugging and monitoring.
- User feedback: Provide clear feedback to users when errors occur, especially for authentication or security-related failures.
- Unsubscribe properly: Always unsubscribe from Observables to prevent memory leaks. Use Angular's
takeUntilpattern or theasyncpipe in templates.
Best Practices
Follow these best practices to ensure optimal performance, security, and user experience when integrating the Angular SDK:
Module Setup
- Use forRoot in root module: Call
KeverdModule.forRoot()in your root module (app.module.ts) to configure the SDK once for your entire application. - Use environment variables: Store your API key in environment variables and never commit it to version control. Use different API keys for development, staging, and production environments.
- Enable debug in development only: Set
debug: trueonly in development environments. Disable it in production to avoid exposing sensitive information in the console.
Service Usage
- Inject service in components: Inject the
KeverdServiceinto your components using Angular's dependency injection. The service is provided as a singleton, so all components share the same instance. - Use RxJS operators: Take advantage of RxJS operators to transform, filter, retry, and handle errors in your data streams. Use
map,catchError,retry, and other operators as needed. - Avoid excessive calls: Don't call
getVisitorData()on every component lifecycle hook or user interaction. Use it strategically for high-value or high-risk operations. - Unsubscribe properly: Always unsubscribe from Observables to prevent memory leaks. Use Angular's
asyncpipe in templates, or use thetakeUntilpattern withOnDestroyin components.
Security
- Protect your API key: Never expose your API key in client-side code that can be viewed in the browser. Use environment variables or a secure configuration management system.
- Use HTTPS: Always use HTTPS endpoints. The SDK will not work with HTTP endpoints for security reasons.
- Validate risk scores: Don't blindly trust risk scores. Use them as one factor in your security decision-making process, along with other signals.
- Monitor for anomalies: Set up monitoring and alerting for unusual patterns in risk scores or error rates.
Performance
- Non-blocking: The SDK is designed to be non-blocking. Data collection and API calls happen asynchronously and won't block your UI.
- Minimal impact: Behavioral data collection is passive and has minimal impact on page performance. The SDK uses efficient event listeners that are automatically cleaned up.
- Bundle size: The SDK is lightweight and has a small bundle size. It won't significantly impact your application's load time.
- RxJS efficiency: Use RxJS operators efficiently. Avoid creating unnecessary subscriptions and use operators like
shareReplayto share Observable streams across multiple subscribers.
Privacy and Compliance
- GDPR compliance: The SDK is designed to be GDPR-compliant. All sensitive data is hashed client-side, and no PII is collected or transmitted.
- User consent: Consider obtaining user consent before initializing the SDK, especially in regions with strict privacy regulations.
- Privacy policy: Update your privacy policy to inform users about data collection and how it's used for fraud detection.
Risk Score Interpretation
| Score Range | Action | Meaning |
|---|---|---|
| 0-29 | allow | Low risk, proceed with login |
| 30-69 | soft_challenge or hard_challenge | Moderate risk, require MFA |
| 70-100 | block | High risk, deny access |
Features
Angular Service
Injectable service following Angular patterns
RxJS Observables
Reactive data access with RxJS
TypeScript Support
Full type definitions included
Module System
Easy setup with forRoot pattern
Requirements
- Angular 15.0 or higher
- RxJS 7.0 or higher
- Modern browser with ES2020 support