Keyri can be used to incorporate sign-in-with-QR functionality into your Supabase app, allowing users to scan a QR code on your web app with your mobile app and be instantly logged into the web app without having to input any credentials.

Configuration is split into Web and Mobile components. On web, the Keyri QR Widget needs to be installed along with an event listener, and in your mobile app, install the Keyri SDK and pass into it the user's refresh token when sign-in-with-QR is initiated. When the refresh token lands in your web app, it's passed into Supabase's setSession() method.

Sign up for Keyri

First make a free account on the Keyri dashboard ( On Add Your Application, set a name and input the domain on which your app will eventually be deployed. You can create multiple application in Keyri to account for your development, staging, and production environments

Note your application key from the Keys and Credentials section - this will be used in the Mobile portion of the implementation


Keyri-Supabase Web Integration Video

For your web app, first download KeyriQR.html (available here) and save it to a public directory.

Next, embed KeyriQR.html in your login page as an iFrame within the desired div. This serves as the widget that displays the dynamic QR code and connects with the Keyri API.

2    <iframe
3        title='KeyriQR'
4        src='/KeyriQR.html'
5        id='qr-frame'
6        height='300'
7        width='300'
8        scrolling='no'
9        style={{ border: 'solid 5px white' }}
10      ></iframe>

Next, for the same login view, set up an event listener to pick up the session token that the iFrame emits when the QR code is scanned by your app.

1useEffect(() => {
2    window.addEventListener('message', async (evt) => {
3      if ( && && document.location.origin == evt.origin) {
4        const { data } = evt;
5        if (!data.error) {
6          let refresh_token = JSON.parse(;
7          await handleQrLogin(refresh_token);
8        } else if (data.error) {
9          console.log(`Keyri error: ${data.message}`);
10        }
11      }

That's it!


Keyri-Supabase Mobile Integration Video

Install Flutter#

First, install the Flutter SDK, found at

Make sure to add Flutter to your PATH, for example:

1export PATH="$PATH:`pwd`/flutter/bin"

Apple - initial setup#

Download the latest version of Xcode from the Mac App Store. Make sure the Xcode provided simulator is using a 64-bit device (iPhone 5s or later). You can check the device by viewing the settings in the simulator’s Hardware > Device or File > Open Simulator menus.

Android - initial setup#

Download the latest version of Android Studio. Install Android SDK and needed emulator(s).

Create Project#

Run this command in your terminal/shell at the desired location for your new project

1$ flutter create my_app

You can then CD into the new directory, and run the test app with

1flutter run

This is a good test - if things are configured correctly so far you should see the default Flutter test app deployed.

Add dependencies (Keyri and Supabase)#

Open your Pubspec.yaml file, which should be at the top level directory in your new project

Add Keyri and Supabase under dependencies

One can now access Supabase and Keyri sdks in their Flutter code

Utilize the two together#

  1. Make a request to Supabase to authenticate the user
  2. Parse the response to extract the token
  3. Authenticate using Keyri
    1. Below, we show how to utilize the EasyKeyriAuth function, which takes the user through scanning the code, creating the session, displaying the confirmation screen, and finalizing the payload transmission
      • Note - you can find your App Key in the Keyri Developer Portal​
    2. Alternatively, intermediate functions in the Keyri SDK, discussed in the mobile docs, can provide control over displaying a custom QR Scanner and/or Confirmation screen
1// Sign in user with email and password
2// Alternatively one can utilize the Supabase API to accomplish the same thing
3final response = await client.auth.signIn(email: 'email', password: 'password');
4if (response.error != null) {
5  // Error
6    print('Error: ${response.error?.message}');
7} else {
8    // Success
9    final session =;
10    // This is the payload that needs to be send through Keyri
11    final refreshToken = session.refreshToken
12    // EasyKeyriAuth guides the user through scanning and parsing the QR, confirming the session, and configuring the payload
13    // One can also use the initiateQRSession method to use the Keyri Scanner with a custom Confirmation screen
14    // Or the ProcessLink method if you have your own scanner or are using deep linking
15    await keyri
16        .easyKeyriAuth([App Key],
17            '{"refreshToken":"$refreshToken"}', [email])
18        .then((authResult) => _onAuthResult(authResult))
19        .catchError((error, stackTrace) => _onError(error));