TypeScript SDK for FrameSentinel Video KYC Verification Platform.
npm install @framesentinel/sdkimport { FrameSentinelClient } from '@framesentinel/sdk';
const client = new FrameSentinelClient({
apiUrl: 'https://api.framesentinel.com',
apiKey: 'your-api-key',
onProgress: (percent) => console.log(`Upload: ${percent}%`),
onStatusChange: (state) => console.log(`Status: ${state}`)
});
// Create session
const session = await client.createSession('user123');
// Upload video
await client.uploadVideo(session.session_id, videoFile);
// Wait for result
const result = await client.pollUntilComplete(session.session_id);
console.log('Risk Level:', result.risk_level);
console.log('Score:', result.authenticity_score);new FrameSentinelClient(config: FrameSentinelConfig)Config Options:
apiUrl(string, required): API endpoint URLapiKey(string, required): Your API keyonProgress(function, optional): Upload progress callbackonStatusChange(function, optional): Processing status callback
createSession(userId: string, deviceMetadata?: DeviceMetadata): Promise<CreateSessionResponse>Creates a new verification session.
Parameters:
userId: External user referencedeviceMetadata: Optional device information
Returns:
{
session_id: string;
state: SessionState;
created_at: string;
}uploadVideo(sessionId: string, videoFile: File): Promise<void>Uploads video for verification. Triggers onProgress callback.
Parameters:
sessionId: Session ID from createSessionvideoFile: Video file to upload
getStatus(sessionId: string): Promise<SessionStatus>Gets current session status.
Returns:
{
session_id: string;
state: SessionState;
updated_at: string;
}getResult(sessionId: string): Promise<VerificationResult>Gets verification result.
Returns:
{
session_id: string;
state: SessionState;
authenticity_score?: number;
risk_level?: RiskLevel;
detection_flags?: DetectionFlags;
frame_timeline?: FrameEvent[];
processed_at?: string;
}pollUntilComplete(
sessionId: string,
maxAttempts?: number,
interval?: number
): Promise<VerificationResult>Polls until processing completes. Triggers onStatusChange callback.
Parameters:
sessionId: Session IDmaxAttempts: Max polling attempts (default: 30)interval: Polling interval in ms (default: 2000)
getDeviceMetadata(): DeviceMetadataCollects device metadata automatically.
type SessionState = 'CREATED' | 'UPLOADED' | 'PROCESSING' | 'ANALYZED' | 'COMPLETED' | 'FAILED';type RiskLevel = 'VERIFIED' | 'SUSPICIOUS' | 'HIGH_RISK';interface DetectionFlags {
deepfake_detected: boolean;
replay_detected: boolean;
injection_detected: boolean;
face_swap_detected: boolean;
metadata_anomaly: boolean;
}interface FrameEvent {
frame_number: number;
timestamp: number;
flags: string[];
confidence: number;
}import { FrameSentinelError } from '@framesentinel/sdk';
try {
const result = await client.pollUntilComplete(sessionId);
} catch (error) {
if (error instanceof FrameSentinelError) {
console.error('Code:', error.code);
console.error('Retryable:', error.retryable);
if (error.retryable) {
// Retry logic
}
}
}Error Codes:
SESSION_CREATE_FAILED: Failed to create sessionUPLOAD_FAILED: Video upload failedNETWORK_ERROR: Network connectivity issueSTATUS_FAILED: Failed to get statusRESULT_FAILED: Failed to get resultPOLLING_TIMEOUT: Processing timeout
import { FrameSentinelClient, FrameSentinelError } from '@framesentinel/sdk';
async function verifyUser(userId: string, videoFile: File) {
const client = new FrameSentinelClient({
apiUrl: 'https://api.framesentinel.com',
apiKey: process.env.FRAMESENTINEL_API_KEY!,
onProgress: (percent) => {
console.log(`Upload progress: ${percent}%`);
},
onStatusChange: (state) => {
console.log(`Processing state: ${state}`);
}
});
try {
// Create session
const session = await client.createSession(userId, {
app_version: '1.0.0',
device_type: 'mobile'
});
console.log('Session created:', session.session_id);
// Upload video
await client.uploadVideo(session.session_id, videoFile);
console.log('Video uploaded successfully');
// Wait for result
const result = await client.pollUntilComplete(session.session_id);
// Handle result
if (result.risk_level === 'VERIFIED') {
console.log('✓ User verified');
console.log('Score:', result.authenticity_score);
return true;
} else {
console.log('✗ Verification failed');
console.log('Risk:', result.risk_level);
console.log('Flags:', result.detection_flags);
return false;
}
} catch (error) {
if (error instanceof FrameSentinelError) {
console.error('Verification error:', error.message);
console.error('Error code:', error.code);
if (error.retryable) {
console.log('Error is retryable, please try again');
}
}
throw error;
}
}import { useState } from 'react';
import { FrameSentinelClient, VerificationResult } from '@framesentinel/sdk';
function VideoVerification() {
const [progress, setProgress] = useState(0);
const [status, setStatus] = useState('');
const [result, setResult] = useState<VerificationResult | null>(null);
const client = new FrameSentinelClient({
apiUrl: 'https://api.framesentinel.com',
apiKey: 'your-api-key',
onProgress: setProgress,
onStatusChange: setStatus
});
const handleVerify = async (videoFile: File) => {
try {
const session = await client.createSession('user123');
await client.uploadVideo(session.session_id, videoFile);
const result = await client.pollUntilComplete(session.session_id);
setResult(result);
} catch (error) {
console.error(error);
}
};
return (
<div>
<input type="file" accept="video/*" onChange={(e) => {
if (e.target.files?.[0]) handleVerify(e.target.files[0]);
}} />
<p>Progress: {progress}%</p>
<p>Status: {status}</p>
{result && (
<div>
<h3>Risk Level: {result.risk_level}</h3>
<p>Score: {result.authenticity_score}</p>
</div>
)}
</div>
);
}import { FrameSentinelClient } from '@framesentinel/sdk';
import fs from 'fs';
async function verifyVideoFile(userId: string, videoPath: string) {
const client = new FrameSentinelClient({
apiUrl: 'https://api.framesentinel.com',
apiKey: process.env.FRAMESENTINEL_API_KEY!
});
// Read file
const buffer = fs.readFileSync(videoPath);
const file = new File([buffer], 'video.mp4', { type: 'video/mp4' });
// Verify
const session = await client.createSession(userId);
await client.uploadVideo(session.session_id, file);
const result = await client.pollUntilComplete(session.session_id);
return result;
}-
Always handle errors
try { await client.uploadVideo(sessionId, file); } catch (error) { if (error instanceof FrameSentinelError && error.retryable) { // Implement retry logic } }
-
Provide user feedback
const client = new FrameSentinelClient({ apiUrl: '...', apiKey: '...', onProgress: (p) => updateProgressBar(p), onStatusChange: (s) => showStatus(s) });
-
Validate video before upload
if (file.size > 100 * 1024 * 1024) { throw new Error('Video too large'); } if (!['video/mp4', 'video/webm'].includes(file.type)) { throw new Error('Invalid format'); }
-
Use environment variables for API keys
const client = new FrameSentinelClient({ apiUrl: process.env.FRAMESENTINEL_API_URL!, apiKey: process.env.FRAMESENTINEL_API_KEY! });
MIT