Passwordless and OTP-less Authentication for your website and app. It helps you to authenticate user via their email or phone number.

Getting Started

To get started, you can create a free account at SAWO to get your API keys.


A step by step series of examples that tell you how to get a development env running. These instructions will let you render the form in your specified container, and allow you to attach successful login callback for futher actions.

Add the plugin in dependencies

  sawo: ^0.1.3

Install the plugin, by running mentioned command

flutter pub get

Import the plugin into class

import 'package:sawo/sawo.dart';

Create API Key

  • Login to sawo dev console.
  • Create a new project
    • Select Hybrid and then select Flutter under that section
    • Set Project Name
  • Copy your API key & Secret Key from the file which has been downloaded automatically.


  • In project/android/app/build.gradle set minSdkVersion to >= 19

  • In project/android/app/src/main/AndroidManifest.xml add this line

<uses-permission android:name="android.permission.INTERNET"/>

Create a Sawo Instance

    Sawo sawo = new Sawo(
        apiKey: <YOUR-API-KEY>,
        secretKey: <YOUR-Secret-Key>,

NOTE: It is always recommended to store your apiKey and secretKey in a .env file. Otherwise, create a separate .dart file and add it to the .gitignore. Just make sure that you are not exposing the keys publicly and also add them to the .gitignore before pushing the project to a public repo.

Redirect User to login page

  • sawo provides two ways to authenticate user, one by email and one by phone number.
  // sawo object for Android/ios
  Sawo sawo = Sawo(
    apiKey: "",
    secretKey: "",

  // user payload
  String user = "";

  void payloadCallback(context, payload) {
    if (payload == null || (payload is String && payload.isEmpty)) {
      payload = "Login Failed :(";
    setState(() {
      user = payload;

  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20),
        child: Column(
          children: [
            Text("UserData :- $user"),
              onPressed: () {
                  context: context,
                  identifierType: 'email',
                  callback: payloadCallback,
              child: const Text('Email Login'),
              onPressed: () {
                  context: context,
                  identifierType: 'phone_number_sms',
                  callback: payloadCallback,
              child: const Text('Phone Login'),

When the user is successfully verified, the callback method will get invoked with the payload containing the userID and other information. It will return empty payload for unsuccessful verification.

Sawo Example Project



This project is licensed under the BSD-3-Clause License