# Visitor Identification

GuardianStack generates a stable, server-issued `visitorId` that persists across sessions, incognito windows, and browser updates. Unlike simple cookies or local identifiers, our visitor ID is computed using advanced signal processing and fuzzy matching on the server, making it highly resistant to spoofing.

***

### How It Works

Visitor identification is a two-step process designed for security:

1. **Client-Side Collection**: The Guardian JS Agent collects anonymous browser signals and sends them to our API. It returns a `requestId`.
2. **Server-Side Resolution**: You send this `requestId` to your backend, which then queries the Guardian API to retrieve the authentic `visitorId` and risk analysis.

This architecture prevents client-side tampering—malicious users cannot simply "edit" their visitor ID in the browser to evade detection.

***

### Integration Guide

#### 1. Client-Side: Generate a Request ID

Install the Guardian JS SDK:

```bash
npm install @guardianstack/guardian-js
```

Initialize the agent and generate a request ID when you need to identify a user (e.g., on login, signup, or payment):

```javascript
import { loadAgent } from "@guardianstack/guardian-js";

// 1. Initialize the agent (usually on app load)
const agentPromise = loadAgent({
  siteKey: "YOUR_PUBLIC_SITE_KEY",
});

// 2. Call this function when a user performs an action
async function getIdentificationToken() {
  const agent = await agentPromise;
  
  // Collect signals and send to Guardian API
  const response = await agent.get();
  const result = await response.json();
  
  // Returns a unique requestId for this specific event
  return result.requestId;
}
```

{% hint style="info" %}
**Note**: The client SDK returns a `requestId`, not the `visitorId` itself. You must send this `requestId` to your server to securely retrieve the identification result.
{% endhint %}

#### 2. Server-Side: Retrieve the Visitor ID

On your backend, use the `requestId` received from the client to fetch the full event details. This ensures you are making decisions based on verified data.

We provide a server-side SDK to make this integration easy and type-safe.

**Install**:

```bash
npm install @guardianstack/guardianjs-server
```

**Implementation**:

```typescript
import { createGuardianClient, isTampering, isVPN } from "@guardianstack/guardianjs-server";

// Initialize the client
const guardian = createGuardianClient({
  secret: process.env.GUARDIAN_SECRET_KEY,
});

// Your backend API handler (e.g., /api/login)
app.post('/api/login', async (req, res) => {
  const { username, password, requestId } = req.body;

  try {
    // 1. Verify the event with GuardianStack
    const event = await guardian.getEvent(requestId);

    // 2. Access the stable visitorId
    const { visitorId } = event.identification;
    console.log(`User ${username} has Visitor ID: ${visitorId}`);

    // 3. (Optional) Check for risks
    if (isTampering(event) || isVPN(event)) {
      return res.status(403).json({ error: 'High risk login attempt blocked' });
    }

    // Example: Check if this visitorId is associated with too many accounts
    const accountCount = await db.users.count({ visitorId });
    if (accountCount > 5) {
      return res.status(403).json({ error: 'Too many accounts for this device' });
    }

    // Proceed with login...
    
  } catch (error) {
    console.error("Guardian check failed:", error);
    return res.status(500).json({ error: 'Security check failed' });
  }
});
```

***

### Understanding the Visitor ID

The `visitorId` is a string (e.g., `h7g9s8d7f6g5...`) that uniquely identifies a visitor's device/browser environment.

#### Stability & Accuracy

GuardianStack uses a sophisticated "fuzzy matching" engine that analyzes over 100 distinct signals, including:

* **Hardware Fingerprints**: GPU renderer, audio stack, hardware concurrency, and memory profiles.
* **Browser Environment**: WebGL capabilities, screen properties, and math computation differences.
* **Network Signals**: IP analysis (when combined with device signals) to handle NAT and dynamic IPs.

**Key Features:**

* **Incognito Resistance**: The ID remains stable even if the user switches to Incognito/Private mode.
* **Tamper Resistance**: Advanced detection algorithms identify and flag attempts to spoof browser signals (e.g., anti-detect browsers).
* **Drift Tolerance**: The ID persists through browser updates and minor configuration changes (like zooming or changing window size).

#### Site-Scoped Privacy

Your `visitorId` values are unique to your `siteKey`. A user visiting Site A and Site B (both using GuardianStack) will have two completely different visitor IDs. This ensures cross-site privacy for users while providing accurate identification for your application.

***

### Best Practices

#### Linking to User Data

GuardianStack does not store your user's PII (Personally Identifiable Information). To associate a visitor ID with a user, you should store the link in your own database.

**Recommended Schema:**

| Column         | Type      | Description                      |
| -------------- | --------- | -------------------------------- |
| `user_id`      | UUID      | Your internal user ID            |
| `visitor_id`   | String    | The GuardianStack visitorId      |
| `last_seen_at` | Timestamp | When this link was last verified |

**Use Cases:**

* **Account Takeover**: If a user logs in with a valid password but a *new* `visitorId`, trigger Multi-Factor Authentication (MFA).
* **Multi-Accounting**: Query your DB to find all users sharing the same `visitorId`.
* **Ban Evasion**: If you ban a `user_id`, also blacklist their `visitorId` to prevent them from creating new accounts.

#### Caching

Do not cache the `visitorId` on the client (e.g., in LocalStorage). Always request a fresh `requestId` for critical actions (Login, Signup, Checkout) to ensure you receive the most up-to-date risk analysis and fraud signals.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.guardianstack.ai/documentation/protect-your-implementation/visitor-identification.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
