---
title: Handling slow internet connections
slug: technical-docs/handling-slow-internet-connections
docTags: 
createdAt: 2026-10-16T10:09:56.799Z
---

The Face Scan plug-in streams video frames to our backend during the whole scan. When the connection is too slow or unstable and we cannot guarantee accurate results, so the scan stops. This minimum connection quality cannot be bypassed. See [Device Requirements](docId\:SFeM-QEJSyws5NGuII1aA).

What you can control is what happens next. This guide shows how to make sure a slow connection never blocks your user journey: the user is told what went wrong, lands on their latest results, and can try again later.

# What the user sees in the plug-in

When the connection is too slow, the plug-in shows a modal that explains the problem and suggests switching networks or moving to a spot with better reception. The user has two options:

- **Try again**: restarts the scan, in case the connection has improved.
- **Quit**: ends the scan. The plug-in sends a `dismiss` message event to your app.



::Image[]{src="https://api.archbee.com/api/optimize/_0R_DnpmBBLLXmaoWvG2u/TVaH2a5g7mU0f1QCVdWe7_file-1b45530934adb14ca35cbb85b1b98f34.png" size="80" isUploading="false" width="2560" height="2000" darkWidth="2560" darkHeight="2000" showCaption="false"}

You do not need to build your own connection message: the plug-in already tells the user that their internet connection is the cause.

# What your app receives

Quitting sends the same `dismiss` event as a completed scan. The only difference is the `hasResults` property:

| Situation                                                  | Event     | `data.hasResults` |
| ---------------------------------------------------------- | --------- | ----------------- |
| Scan completed                                             | `dismiss` | `true`            |
| Scan stopped (slow connection, poor conditions, user quit) | `dismiss` | `false`           |

This means you can use a single event to continue your flow, whatever the outcome of the scan.

```json
{
  "stage": "dismiss",
  "data": {
    "hasResults": false
  }
}
```

:::hint{type="info"}
The `dismiss` event does not state why the scan was stopped. A slow connection, poor lighting and a user who chose to quit all result in `hasResults: false`. Keep the message in your app general, for example "We couldn't complete your scan this time", and mention the connection as one of the possible causes.
:::

# Recommended flow

1. **Listen for the `dismiss` event.** See [Listening to message events in webapps](docId:1PHy94PhTtsVFmacmKePV) or the guide for your [Embed in mobile app](docId\:wyTSjD2MUuwcxGOhTmsJV). Our mobile SDKs close the web view automatically on `dismiss`.
2. **Close the plug-in and go to your results page**, whatever the value of `hasResults`. Unmount or replace the iframe rather than changing its `src`.
3. **If `hasResults` is `false` , navigate to the results page**
   Results from earlier scans stay available (see below).
4. **Offer a way to try again later**, for example a button that opens a new Face Scan. Always request a new plug-in URL for a new scan.

### Example (web app)

```javascript
window.addEventListener("message", (event) => {
  if (!event.origin.includes("intelliprove.com")) return;
  if (event.data?.stage !== "dismiss") return;

  // Close the plug-in, whatever the outcome
  document.getElementById("intelliprove-iframe").remove();

  // Continue to the results page, flagging an incomplete scan
  const scanCompleted = event.data.data?.hasResults === true;
  showResultsPage({ scanCompleted });
});
```

# Showing the latest results

How you show the previous results depends on your integration:

| Integration                                | What to do                                                                                                                                                               |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Health Dashboard** or **IntelliWidgets** | Nothing extra. The dashboard and widgets always show the user's most recent completed scan.                                                                              |
| **Rest API**                               | Request the latest results with [Rest API](docId\:BiuPVixvHltbukKLR2ATI) (`GET /v2/face_scans/latest`) and [Rest API](docId\:BiuPVixvHltbukKLR2ATI) (`GET /v2/metrics`). |

:::hint{type="warning"}
**First-time users have no previous results.** If the very first scan of a user is stopped, there is nothing to show yet. Show an empty state instead, for example: *"Your first scan could not be completed. Try again when you have a stable internet connection."*
:::

# Checklist

- [ ] Your app listens for the `dismiss` event and closes the plug-in.
- [ ] The user always continues to the next step, also when `hasResults` is `false`.
- [ ] An incomplete scan shows a short, neutral message and the latest results.
- [ ] First-time users without results see an empty state with a way to try again.
- [ ] Starting a new scan requests a new plug-in URL.

