Fingerprint SDK

Fingerprint SDK Integration

A browser fingerprint is a unique digital identifier derived from browser and device characteristics: OS version, screen resolution, installed fonts, plugins, timezone, language, and more.

Embermind provides a proprietary SDK that collects fingerprints and automatically sends them to the antifraud system.


Getting Started

  1. Contact your manager to obtain:

    • Your personal fingerprint domain (e.g., fp.yourcompany.com)
    • Your API key
  2. Add the SDK to your checkout page (see integration examples below)


HTML Integration

Basic Setup:

<script src="https://fp.yourcompany.com/sdk.js"></script>
<script>
    const fp = new EmbermindFingerprint.Fingerprint({
        domain: 'https://fp.yourcompany.com',
        apiKey: 'YOUR_API_KEY',
        sessionId: 'TRANSACTION_ID'
    });
</script>

Full Page Example:

<!DOCTYPE html>
<html>
<head>
    <title>Checkout</title>
</head>
<body>
    <!-- Your checkout form -->
    
    <script src="https://fp.yourcompany.com/sdk.js"></script>
    <script>
        const fp = new EmbermindFingerprint.Fingerprint({
            domain: 'https://fp.yourcompany.com',
            apiKey: 'YOUR_API_KEY',
            sessionId: 'txn_12345',
            extendedChecks: true
        });
        
        fp.onComplete((success, error) => {
            if (!success) {
                console.error('Fingerprint error:', error);
            }
        });
    </script>
</body>
</html>

React Integration

import { useEffect } from 'react';
import { Fingerprint } from '@embermind/embermind-fingerprint';

function CheckoutPage({ transactionId }: { transactionId: string }) {
    useEffect(() => {
        const fp = new Fingerprint({
            domain: 'https://fp.yourcompany.com',
            apiKey: process.env.REACT_APP_EMBERMIND_KEY,
            sessionId: transactionId,
            extendedChecks: true
        });
        
        fp.onComplete((success) => {
            console.log('Fingerprint:', success ? 'sent' : 'failed');
        });
    }, [transactionId]);
    
    return <div>Your checkout form</div>;
}

Next.js Integration

import { useEffect } from 'react';
import { Fingerprint } from '@embermind/embermind-fingerprint';

export default function CheckoutPage({ transactionId }: { transactionId: string }) {
    useEffect(() => {
        if (typeof window !== 'undefined') {
            const fp = new Fingerprint({
                domain: 'https://fp.yourcompany.com',
                apiKey: process.env.NEXT_PUBLIC_EMBERMIND_KEY,
                sessionId: transactionId,
                extendedChecks: true
            });
        }
    }, [transactionId]);
    
    return <div>Your checkout form</div>;
}

Vue.js Integration

<script setup lang="ts">
import { onMounted } from 'vue';
import { Fingerprint } from '@embermind/embermind-fingerprint';

const props = defineProps<{ transactionId: string }>();

onMounted(() => {
    const fp = new Fingerprint({
        domain: 'https://fp.yourcompany.com',
        apiKey: import.meta.env.VITE_EMBERMIND_KEY,
        sessionId: props.transactionId,
        extendedChecks: true
    });
});
</script>

Configuration Options

OptionTypeRequiredDescription
domainstringYesYour personal domain (provided by manager)
apiKeystringYesYour API key (provided by manager)
sessionIdstringYesYour transaction or session ID
extendedChecksbooleanNoEnable VM/bot detection (recommended: true)
fpcomApiKeystringNoFingerprintJS Pro API key (optional)
fpcomDomainstringNoFingerprintJS Pro endpoint (optional)
timeoutnumberNoCollection timeout in ms (default: 5000)

Full Configuration Example

const fp = new EmbermindFingerprint.Fingerprint({
    // Required - provided by your manager
    domain: 'https://fp.yourcompany.com',
    apiKey: 'em_live_abc123...',
    
    // Required - your transaction ID
    sessionId: 'txn_payment_98765',
    
    // Recommended
    extendedChecks: true,
    
    // Optional: FingerprintJS Pro integration
    fpcomApiKey: 'your-fingerprintjs-pro-key',
    fpcomDomain: 'https://metrics.yoursite.com'
});

Automatic Session ID from URL

If your page URL contains ?client_transaction_id=XXX, the SDK will use it automatically:

https://yoursite.com/checkout?client_transaction_id=txn_abc123

In this case, you can omit sessionId in options — it will be extracted from the URL.


FingerprintJS Pro Integration (Optional)

If you have a FingerprintJS Pro subscription, you can include their visitorId in the fingerprint data for enhanced accuracy:

const fp = new EmbermindFingerprint.Fingerprint({
    domain: 'https://fp.yourcompany.com',
    apiKey: 'YOUR_API_KEY',
    sessionId: 'txn_12345',
    
    // FingerprintJS Pro credentials
    fpcomApiKey: 'YOUR_FINGERPRINTJS_PRO_KEY',
    fpcomDomain: 'https://fpmetrics.yoursite.com'
});

This sends both Embermind fingerprint and FingerprintJS Pro visitorId together.


Extended Checks

When extendedChecks: true is enabled, the SDK collects additional data for VM and bot detection:

Collected Data:

  • CPU timing patterns
  • Memory access patterns
  • Timer precision analysis
  • Canvas rendering timing
  • Crypto operation timing

Detects:

  • Virtual machines (VMware, VirtualBox, Hyper-V)
  • Headless browsers (Puppeteer, Playwright, Selenium)
  • Browser automation tools
  • Emulators

Recommendation: Always enable extendedChecks: true for payment and registration pages.


Completion Callback

Track when fingerprint collection completes:

const fp = new EmbermindFingerprint.Fingerprint({
    domain: 'https://fp.yourcompany.com',
    apiKey: 'YOUR_API_KEY',
    sessionId: 'txn_12345'
});

fp.onComplete((success, error) => {
    if (success) {
        console.log('Fingerprint sent successfully');
        // Proceed with payment/action
    } else {
        console.error('Fingerprint failed:', error);
        // Handle error (optional - don't block user)
    }
});

Browser Compatibility

BrowserMinimum Version
Chrome80+
Firefox113+
Safari16.4+
Edge80+
Opera67+

Best Practices

  1. Initialize early — Add SDK at the start of page load
  2. Use transaction ID — Always pass your transaction/session ID for correlation
  3. Enable extended checks — Use extendedChecks: true on sensitive pages
  4. Don't block on errors — If fingerprint fails, allow user to proceed
  5. Use HTTPS — Your page must be served over HTTPS

Troubleshooting

Fingerprint not sending

  1. Check browser console for errors
  2. Verify domain and apiKey are correct
  3. Ensure page is served over HTTPS
  4. Verify DNS is configured for your domain

onComplete not firing

  1. Verify domain is provided
  2. Check if page closes before collection completes

Retrieving Fingerprint Data via API

After fingerprints are collected, you can retrieve them through the API.

Authentication: All API requests require either x-access-token or x-api-key header.


Authentication

You can authenticate using one of two methods:

MethodHeaderDescription
Access Tokenx-access-tokenObtained from /api/v1/client/auth/login
API Keyx-api-keyCreated in Settings → API Keys

Example with Access Token:

curl -X POST 'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-list' \
  -H 'Content-Type: application/json' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiIs...' \
  -d '{"transactionExternalId": "txn_123"}'

Example with API Key:

curl -X POST 'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-list' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: em_live_abc123def456...' \
  -d '{"transactionExternalId": "txn_123"}'

Note: API keys must have appropriate permissions configured to access fingerprint endpoints.


Get Fingerprints List

Retrieve a paginated list of fingerprints. Can filter by transaction ID or external transaction ID.

Endpoint: POST /api/v1/client/fingerprints/internal/get-list

Headers:

HeaderRequiredDescription
x-access-tokenOne ofAccess token
x-api-keyOne ofAPI key

Request Body:

FieldTypeRequiredDescription
transactionIdstring (UUID)NoFilter by internal transaction ID
transactionExternalIdstringNoFilter by external transaction ID (your sessionId)
pagenumberNoPage number, starts from 1 (default: 1)
perPagenumberNoItems per page (default: 20)

curl Example — Get by Transaction ID:

curl -X POST 'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-list' \
  -H 'Content-Type: application/json' \
  -H 'x-access-token: YOUR_ACCESS_TOKEN' \
  -d '{
    "transactionId": "69e45d20-98a9-4c75-ab60-1188d64d510a",
    "page": 1,
    "perPage": 10
  }'

curl Example — Get by External Transaction ID:

curl -X POST 'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-list' \
  -H 'Content-Type: application/json' \
  -H 'x-access-token: YOUR_ACCESS_TOKEN' \
  -d '{
    "transactionExternalId": "txn_payment_98765",
    "page": 1,
    "perPage": 10
  }'

Response:

FieldTypeDescription
countnumberTotal count of fingerprints
dataListarrayList of fingerprint objects

Fingerprint Object:

FieldTypeDescription
idstring (UUID)Unique fingerprint ID
fingerprintInternalstring | nullSHA256 fingerprint hash
fingerprintExternalstring | nullExternal fingerprint (visitorId from fingerprint.com)
fingerprintClientstring | nullClient-generated fingerprint identifier
createdAtstringCreation timestamp (ISO 8601)
companyIdstring (UUID)Company ID

Example Response:

{
    "count": 2,
    "dataList": [
        {
            "id": "69e45d20-98a9-4c75-ab60-1188d64d510a",
            "fingerprintInternal": "a1b2c3d4e5f6789...",
            "fingerprintExternal": "fp_visitor_abc123xyz",
            "fingerprintClient": "fingerprint_client_123",
            "createdAt": "2025-01-28T12:30:00.027Z",
            "companyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
        },
        {
            "id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
            "fingerprintInternal": "xyz789abc123def...",
            "fingerprintExternal": null,
            "fingerprintClient": "fingerprint_client_456",
            "createdAt": "2025-01-28T12:25:00.027Z",
            "companyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
        }
    ]
}

Get Single Fingerprint Details

Retrieve detailed information about a specific fingerprint, including all associated sessions with raw browser data.

Endpoint: POST /api/v1/client/fingerprints/internal/get-one

Headers:

HeaderRequiredDescription
x-access-tokenOne ofAccess token
x-api-keyOne ofAPI key

Request Body:

FieldTypeRequiredDescription
fingerprintIdstring (UUID)YesFingerprint ID to retrieve

curl Example:

curl -X POST 'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-one' \
  -H 'Content-Type: application/json' \
  -H 'x-access-token: YOUR_ACCESS_TOKEN' \
  -d '{
    "fingerprintId": "69e45d20-98a9-4c75-ab60-1188d64d510a"
  }'

Response:

FieldTypeDescription
idstring (UUID)Unique fingerprint ID
fingerprintInternalstring | nullSHA256 fingerprint hash
fingerprintExternalstring | nullExternal fingerprint (visitorId from fingerprint.com)
fingerprintClientstring | nullClient-generated fingerprint identifier
createdAtstringFingerprint creation timestamp (ISO 8601)
companyIdstring (UUID)Company ID
sessionListarrayList of collection sessions for this fingerprint

Session Object:

FieldTypeDescription
idstring (UUID)Session record ID
sessionIdstring | nullSession identifier (your transaction external ID)
rawDataobjectComplete fingerprint data (TCP, TLS, HTTP, Client, Bot detection)
createdAtstringSession creation timestamp (ISO 8601)
fingerprintApiKeyIdstring (UUID) | nullAPI key ID used for collection

Example Response:

{
    "id": "69e45d20-98a9-4c75-ab60-1188d64d510a",
    "fingerprintInternal": "a1b2c3d4e5f6789...",
    "fingerprintExternal": "fp_visitor_abc123xyz",
    "fingerprintClient": "fingerprint_client_123",
    "createdAt": "2025-01-28T12:30:00.027Z",
    "companyId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "sessionList": [
        {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "sessionId": "txn_payment_98765",
            "rawData": {
                "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...",
                "screenResolution": "1920x1080",
                "timezone": "Europe/Moscow",
                "timezoneOffset": -180,
                "language": "en-US",
                "languages": ["en-US", "en"],
                "platform": "Win32",
                "hardwareConcurrency": 8,
                "deviceMemory": 8,
                "colorDepth": 24,
                "canvas": "hash_abc123...",
                "webgl": {
                    "vendor": "Google Inc. (NVIDIA)",
                    "renderer": "ANGLE (NVIDIA, ...)"
                },
                "fonts": ["Arial", "Times New Roman", "Courier New"],
                "audio": "hash_audio123...",
                "botDetection": {
                    "isBot": false,
                    "isFake": false,
                    "isVm": false,
                    "isHeadless": false
                }
            },
            "createdAt": "2025-01-28T12:30:00.027Z",
            "fingerprintApiKeyId": "b2c3d4e5-f6a7-8901-bcde-f23456789012"
        }
    ]
}

Raw Data Fields Reference

The rawData object contains detailed browser and device information:

CategoryFieldsDescription
BrowseruserAgent, language, languages, platformBrowser identification
ScreenscreenResolution, colorDepth, devicePixelRatioDisplay characteristics
HardwarehardwareConcurrency, deviceMemoryCPU and memory info
Timetimezone, timezoneOffsetUser timezone
CanvascanvasCanvas fingerprint hash
WebGLwebgl.vendor, webgl.rendererGPU information
AudioaudioAudio context fingerprint
FontsfontsInstalled system fonts
Bot DetectionbotDetection.isBot, isFake, isVm, isHeadlessAutomation detection flags

Error Responses

Fingerprint Not Found (404):

{
    "statusCode": 404,
    "error": "NOT_FOUND",
    "message": "Fingerprint not found"
}

Invalid Request (400):

{
    "statusCode": 400,
    "error": "BAD_REQUEST",
    "message": "fingerprintId must be a valid UUID"
}

Unauthorized (401) — Invalid Token:

{
    "statusCode": 401,
    "error": "UNAUTHORIZED",
    "message": "Invalid or expired access token"
}

Unauthorized (401) — Invalid API Key:

{
    "statusCode": 401,
    "error": "UNAUTHORIZED",
    "message": "API key is incorrect or inactive"
}

Forbidden (403) — Insufficient Permissions:

{
    "statusCode": 403,
    "error": "FORBIDDEN",
    "message": "API key does not have permission to access this endpoint"
}

Usage Examples

JavaScript/Node.js (with API Key):

const axios = require('axios');

const API_KEY = 'em_live_abc123def456...';

// Get fingerprints by transaction
const response = await axios.post(
    'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-list',
    {
        transactionExternalId: 'txn_payment_98765',
        page: 1,
        perPage: 10
    },
    {
        headers: {
            'Content-Type': 'application/json',
            'x-api-key': API_KEY
        }
    }
);

console.log(`Found ${response.data.count} fingerprints`);
for (const fp of response.data.dataList) {
    console.log(`Fingerprint: ${fp.id}, Internal: ${fp.fingerprintInternal}`);
}

Python (with API Key):

import requests

API_KEY = 'em_live_abc123def456...'

# Get single fingerprint details
response = requests.post(
    'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-one',
    json={'fingerprintId': '69e45d20-98a9-4c75-ab60-1188d64d510a'},
    headers={
        'Content-Type': 'application/json',
        'x-api-key': API_KEY
    }
)

data = response.json()
print(f"Fingerprint: {data['fingerprintInternal']}")
print(f"Sessions: {len(data['sessionList'])}")

for session in data['sessionList']:
    print(f"  Session {session['sessionId']}: Bot={session['rawData'].get('botDetection', {}).get('isBot')}")

PHP (with API Key):

<?php
$apiKey = 'em_live_abc123def456...';
$ch = curl_init();

curl_setopt_array($ch, [
    CURLOPT_URL => 'https://api.embermind.xyz/api/v1/client/fingerprints/internal/get-list',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'x-api-key: ' . $apiKey
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'transactionExternalId' => 'txn_payment_98765',
        'page' => 1,
        'perPage' => 10
    ])
]);

$response = curl_exec($ch);
$data = json_decode($response, true);

echo "Found " . $data['count'] . " fingerprints\n";
foreach ($data['dataList'] as $fp) {
    echo "Fingerprint: " . $fp['id'] . "\n";
}
?>

---

## Support

For integration support, contact your Embermind manager.