/
Contact usSee pricingStart building
Node
​

    About Stytch

    Introduction
    Integration Approaches
      Full-stack overview
      Frontend (pre-built UI)
      Frontend (headless)
      Backend
    Migrations
      Migration overview
      Migrating users statically
      Migrating users dynamically
      Additional migration considerations
      Zero-downtime deployment
      Defining external IDs for users
      Migrating from Stytch Consumer to B2B
      Exporting from Stytch
    Custom Domains
      Overview

    Authentication

    DFP Protected Auth
      Overview
      Setting up DFP Protected Auth
      Handling challenges
    Magic Links
    • Email Magic Links

      • Getting started with the API
        Getting started with the SDK
        Replacing your password reset flow
        Building an invite user flow
        Add magic links to an existing auth flow
        Adding PKCE to a Magic Link flow
        Magic Link redirect routing
    • Embeddable Magic Links

      • Getting started with the API
    MFA
      Overview
      Backend integration
      Frontend integration
      Remembered device flow
    Mobile Biometrics
      Overview
    M2M Authentication
      Authenticate an M2M Client
      Rotate client secrets
      Import M2M Clients from Auth0
    OAuth
    • Identity providers

      • Overview
        Provider setup
      Getting started with the API (Google)
      Add Google One Tap via the SDK
      Email address behavior
      Adding PKCE to an OAuth flow
    Connected Apps
      Overview
      Getting started with the SDK
      Getting started with the API
      Client types
      OAuth scopes
    • Integration Guides

      • Integrate with an Existing Auth System
        MCP Authorization Overview
        Integrate with MCP servers deployed on Cloudflare
        Integrate with MCP servers on Vercel
        Integrate with CLI Apps
        Integrate with AI agents
    • Resources

      • Consent Management
        Custom Domains
        Testing Integrations
    Passcodes
      Getting started with the API
      Getting started with the SDK
    • Toll fraud

      • What is SMS toll fraud?
        How you can prevent toll fraud
      Unsupported countries
    Passkeys & WebAuthn
    • Passkeys

      • Passkeys overview
        Set up Passkeys with the frontend SDK
    • WebAuthn

      • Getting started with the API
        Getting started with the SDK
    Passwords
      Getting started with the API
      Getting started with the SDK
      Password strength policy
    • Email verification

      • Overview
        Email verification before password creation
        Email verification after password creation
    Sessions
      How to use sessions
      Backend integrations
      Frontend integrations
      Custom claims
      Custom claim templates
      Session tokens vs JWTs
      How to use Stytch JWTs
    TOTP
      Getting started with the API
      Getting started with the SDK
    Web3
      Getting started with the API
      Getting started with the SDK
    Trusted Auth Tokens
      Overview
      Getting Started with External IDPs
      Getting Started with Custom Auth Factors
    Device History
      New device notifications

    RBAC

    Resources
      Overview
      Role assignment
    Integration Guides
      Start here
      Backend integration
      Headless frontend integration
      (Legacy) Implement RBAC with metadata

    3rd Party Integrations

    Planetscale
    Supabase
    Feathery
    Unit

    Testing

    E2E testing
    Sandbox values
Get support on SlackVisit our developer forum

Contact us

Consumer Authentication

/

Guides

/

Authentication

/

Device History

/

New device notifications

New device notifications

Detecting and alerting on logins from new devices, IP addresses, or locations is a key security measure to help identify potentially unauthorized access to user accounts. By notifying users when their account is accessed from an unfamiliar place, they can take immediate action like revoking sessions, resetting their password, or contacting support.

You can easily send notifications for new devices, IP address, and login locations by using Stytch Device Fingerprinting. At a high level, you will include a Telemetry ID (for device information) in your authentication requests. Stytch will return new device flags in the authentication response and as a webhook event.

Flowchart Showing Webhooks

In this guide, you will learn how to use Stytch’s user device history feature to send notifications about new devices. You will:

  1. Collect device fingerprints from the frontend and submit them as part of the authentication request
  2. Use the Stytch response or webhook to detect new devices
  3. Implement your own method to notify your user about unusual logins

Prerequisites

  1. A Stytch project for Consumer Authentication.
    • If you don't have one already, in the Dashboard, click on your existing project name in the top left corner of the Dashboard, click Create Project, and then select Consumer Authentication.
  2. Access to Stytch Device Fingerprinting if you don't have it already.
  3. An application that has already implemented an authentication method with Stytch.

Collecting device fingerprints and submitting them

You will use Stytch Device Fingerprinting to collect device information. The implementation differs depending on whether you use a frontend SDK or a backend SDK.

Frontend SDK or Mobile SDK

If you’re using one of Stytch's frontend or mobile SDKs , you can automatically collect and submit fingerprints by turning on Protected Auth.

On the dashboard Frontend SDK page, under optional configuration, enable Protected Auth.

Enable Protected Auth Screenshot

In observation mode, this will collect and record device information. In enforcement mode, Protected Auth will also block authentication attempts that receive a BLOCK verdict. For sending new device notifications, you can use either mode.

Backend SDK or API

This code snippet is equivalent to steps 1 and 2 of the Getting Started guide here.

If you’re using one of Stytch's backend SDKs or integrating directly with the Stytch API, you will need to add the Device Fingerprinting script to your application frontend, call GetTelemetryID(), and pass the resulting Telemetry ID to the backend SDK call.

In your application frontend:

<html>
<head>
    <script src="https://elements.stytch.com/telemetry.js"></script>
</head>
<body>
    <button id="login" onclick="login()">Click here to login!</button>

    <script>
        function login() {
            var publicToken = "public-token-test-feee2622-4abc-46a8-9609-a27130735214"; // public token from Stytch Dashboard
            GetTelemetryID({
                publicToken: publicToken
            }).then((telemetry_id) => {
                var request = new XMLHttpRequest();
                request.open('POST', 'https://www.customer.com/login', true);
                 // include telemetry_id as part of the login request
                request.setRequestHeader('X-Telemetry-ID', telemetry_id);
                request.send(null);
            });
        }
    </script>
</body>
</html>

Then in your backend, include the telemetry ID in your authenticate request to Stytch. To see which endpoints accept a telemetry ID, reference the API documentation .

(req, res) => {
  const telemetryId = req.headers['x-telemetry-id'];

  const params = {
    token: "SeiGwdj5lKkrEVgcEY3QNJXt6srxS3IK2Nwkar6mXD4=",
    telemetry_id: telemetryId,  // include the telemetry_id
  };

  const response = await client.magicLinks.authenticate(params);
  console.log(response);
};

Now, Stytch will store the device information for the user and will return information about whether the device is new or has been previously seen.

Detecting new devices through webhook or response

You can detect new devices in two ways:

  • Using a webhook sent by Stytch
  • Or, in the response body from the authenticate request

Webhook

You can use webhooks to receive data about new devices.

If you’re using one of Stytch's frontend or mobile SDKs, this is the only way to send new device notifications. If you’re using a backend integration, you can use either webhooks or the authenticate response.

Webhooks enable you to de-couple the core application logic and any notifications you send.

In the Webhooks page of the Dashboard, you will configure a new webhook URL. Your application should listen on this URL for new device events.

Webhook Configuration Screenshot

You can subscribe to the direct.user_device.new_device_attribute event to receive notifications about new devices. The resulting events will look like this:

USER_DEVICE = {
  "action": "NEW_DEVICE_ATTRIBUTE",
  "event_id": "webhook-test-...",
  "id": "user-test-...",
  "object_type": "user_device",
  "project_id": "project-test-...",
  "source": "DIRECT",
  "timestamp": "2025-01-02-...",
  "vertical": "CONSUMER",
  "user_device": {
    "visitor_id": "visitor-...",
    "visitor_id_details": {
      "is_new": true,
      "first_seen_at": "2025-01-02-....",
      "last_seen_at": null
    },
    "ip_address": "1.2.3.4",
    "ip_address_details": {
      "is_new": false,
      "first_seen_at": "2024-12-02-....",
      "last_seen_at": "2025-01-02-...."
    },
    "ip_geo_city": "San Francisco",
    "ip_geo_country": "US",
    "ip_geo_country_details": {
      "is_new": false,
      "first_seen_at": "2024-11-02-....",
      "last_seen_at": "2025-01-02-...."
    },
    "ip_geo_region": "California"
  }
}

The field .is_new will be true if this is the first time this user has been seen with this device, IP address, or country (based on IP geolocation). You can also use the first_seen_at and last_seen_at fields for additional context.

If a user logs in with a combination of device, IP address, and country that are all known, no webhook event will be sent.

You can write custom code that listens for the new_device_attribute and when a new device is detected, notify the user through email, push notification, or in-app inbox.

Authenticate response (backend only)

WARNING: The new device data in the response body should only be used in backend integrations. On the frontend, an attacker could modify the response body, so it should not be used for security-sensitive purposes in a frontend integration.

If you are using a backend integration, you can use the response body to detect new devices and send notifications.

Every endpoint supported by user device history will return a user_device field. For example, if you are using Email Magic Links, the response will look something like this:

{
  "user_device": {
    "visitor_id": "visitor-....",
    "visitor_id_details": {
      "is_new": true,
      "first_seen_at": "2025-01-02-....",
      "last_seen_at": null
    },
    "ip_address": "1.2.3.4",
    "ip_address_details": {
      "is_new": false,
      "first_seen_at": "2024-12-02-....",
      "last_seen_at": "2025-01-02-...."
    },
    "ip_geo_city": "San Francisco",
    "ip_geo_country": "US",
    "ip_geo_country_details": {
      "is_new": false,
      "first_seen_at": "2024-11-02-....",
      "last_seen_at": "2025-01-02-...."
    },
    "ip_geo_region": "California"
  },
  "session": {
    "authentication_factors": [
      {
        "delivery_method": "email",
        ...
      }
    ],
    "custom_claims": {},
    ...
  }
  "user_id": "user-live-..",
  ...
},

You can then write your custom code that handles new devices, like sending the user a notification through email, push notification, or in-app inbox.

Best practices for notifications

Once you’ve detected a login from a new device, you can notify them.

Here are a few things to keep in mind when sending new device notifications:

  1. “Not me” action
  2. Balancing signal and noise
  3. Latency considerations

“Not me” action

Your new device notification should include a “Not me” action to take if the login was not actually coming from the real user. When the user selects “Not me”, you can respond immediately to the suspicious login:

  • Help them contact your support team with relevant information
  • Automatically revoke all sessions associated with that user
  • For password-based logins, you can reset the password

In the longer term, you can help improve their account security:

  • Increase your password requirements, including turning on breach detection
  • Switch away from password-based logins to use more secure options like passwordless (magic links) or OAuth
  • Add MFA through SMS, TOTP, or Passkeys

Balancing signal and noise

A new device is not necessarily an indicator of a bad actor attempting to log in. The three new device attributes will naturally change over time for real users:

  • The visitor_id may change due to users switching browsers or clearing their cache.
  • IP addresses change naturally. Users may switch networks during normal usage, especially on mobile devices or when using VPNs. Even on the same network, Internet Service Providers (ISPs) may change the IP address of a client.
  • The ip_geo_country is based on IP address and may change more frequently in geographical areas where multiple countries are close to each other.

You can observe your own traffic to see which factors are most useful for your users, and tailor your notifications accordingly. For example, you may find that within your user base, IP addresses change often, so you can send a notification only if the visitor ID or country change as well. You can also contact Stytch support for help designing your notifications.

Latency considerations

If you are using the authenticate response in your backend integration, consider the latency impact.

For example, when a user logs in from a new device, you may want to send a notification via email. Sending an email can take multiple seconds, so it would be a poor experience if the user needed to wait for the email to be sent before they completed their login.

Instead of synchronously sending notifications in your application code, you can send notifications async or add them to a task queue, while immediately returning the logged-in session to the user.

Prerequisites

Collecting device fingerprints and submitting them

Frontend SDK or Mobile SDK

Backend SDK or API

Detecting new devices through webhook or response

Webhook

Authenticate response (backend only)

Best practices for notifications

“Not me” action

Balancing signal and noise

Latency considerations