/
Contact usSee pricingStart building

    About B2B SaaS Authentication

    Introduction
    Stytch B2B Basics
    Integration Approaches
      Full-stack overview
      Frontend (pre-built UI)
      Frontend (headless)
      Backend
    Next.js
      Routing
      Authentication
      Sessions
    Migrations
      Overview
      Reconciling data models
      Migrating user data
      Additional migration considerations
      Zero-downtime deployment
      Defining external IDs
      Migrating from Stytch Consumer to B2B
      Exporting from Stytch
    Custom Domains
      Overview

    Authentication

    Single Sign On
    • Resources

      • Overview
        External SSO Connections
        Standalone SSO
    • Integration Guides

      • Start here
        Provider setup
        Backend integration guide
        Headless integration guide
        Pre-built UI integration guide
    OAuth
    • Resources

      • Overview
        Authentication flows
        Identity providers
        Google One Tap
        Provider setup
    • Integration Guides

      • Start here
        Backend integration
        Headless frontend integration
        Pre-built UI frontend integration
    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 a remote MCP server
        Integrate with AI agents
    • Resources

      • Consent Management
        Custom Domains
        Testing Integrations
    Sessions
    • Resources

      • Overview
        JWTs vs Session Tokens
        How to use Stytch JWTs
        Custom Claims
        Custom Claim Templates
    • Integration Guides

      • Start here
        Backend integration
        Frontend integration
    Email OTP
      Overview
    Magic Links
    • Resources

      • Overview
        Email Security Scanner Protections
    • Integration Guides

      • Start here
        Backend integration
        Headless frontend integration
        Pre-built UI frontend integration
    Multi-Factor Authentication
    • Resources

      • Overview
    • Integration Guides

      • Start here
        Backend integration
        Headless frontend integration
        Pre-built UI frontend integration
    Passwords
    • Resources

      • Overview
        Strength policy
    • Integration Guides

      • Pre-built UI frontend integration
    UI components
      Overview
      Implement the Discovery flow
      Implement the Organization flow
    DFP Protected Auth
      Overview
      Setting up DFP Protected Auth
      Handling challenges
    M2M Authentication
      Authenticate an M2M Client
      Rotate client secrets
      Import M2M Clients from Auth0
    Trusted Auth Tokens
      Overview
      Getting Started with External IDPs
      Getting Started with Custom Auth Factors
    Device History
      New device notifications

    Authorization & Provisioning

    RBAC
    • Resources

      • Overview
        Stytch Resources & Roles
        Role assignment
    • Integration Guides

      • Start here
        Backend integration
        Headless frontend integration
    SCIM
    • Resources

      • Overview
        Supported actions
    • Integration Guides

      • Using Okta
        Using Microsoft Entra
    Organizations
      Managing org settings
      JIT Provisioning

    Testing

    E2E testing
    Sandbox values
Get support on SlackVisit our developer forum

Contact us

B2B SaaS 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 B2B 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 B2B 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 = {
    magic_links_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 member 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.member_device.new_device_attribute event to receive notifications about new devices. The resulting events will look like this:

MEMBER_DEVICE = {
  "action": "NEW_DEVICE_ATTRIBUTE",
  "event_id": "webhook-test-...",
  "id": "member-test-...",
  "object_type": "member_device",
  "project_id": "project-test-...",
  "source": "DIRECT",
  "timestamp": "2025-01-02-...",
  "vertical": "B2B",
  "member_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 member device history will return a member_device field. For example, if you are using Email Magic Links, the response will look something like this:

{
  "member_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"
  },
  "member_session": {
    "authentication_factors": [
      {
        "delivery_method": "email",
        ...
      }
    ],
    "custom_claims": {},
    ...
  }
  "member_id": "member-live-..",
  ...
},

You can then write your custom code that handles new devices, like sending the member 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 member
  • 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/SSO
  • Add MFA through SMS or TOTP

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