diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
index 671992ca02f0268e7fad0fe2ffee536ae41c7e1c..7048c48d0d81b7e5bb1b9ef27c9f5c2ad005f28c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
@@ -3,8 +3,10 @@ package se.leap.bitmaskclient.base.models;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URLEncoder;
 
 public class Introducer implements Parcelable {
     private String type;
@@ -13,12 +15,15 @@ public class Introducer implements Parcelable {
     private String fullyQualifiedDomainName;
     private boolean kcpEnabled;
 
-    public Introducer(String type, String address, String certificate, String fullyQualifiedDomainName, boolean kcpEnabled) {
+    private String auth;
+
+    public Introducer(String type, String address, String certificate, String fullyQualifiedDomainName, boolean kcpEnabled, String auth) {
         this.type = type;
         this.address = address;
         this.certificate = certificate;
         this.fullyQualifiedDomainName = fullyQualifiedDomainName;
         this.kcpEnabled = kcpEnabled;
+        this.auth = auth;
     }
 
     protected Introducer(Parcel in) {
@@ -27,6 +32,7 @@ public class Introducer implements Parcelable {
         certificate = in.readString();
         fullyQualifiedDomainName = in.readString();
         kcpEnabled = in.readByte() != 0;
+        auth = in.readString();
     }
 
     public String getFullyQualifiedDomainName() {
@@ -40,6 +46,7 @@ public class Introducer implements Parcelable {
         dest.writeString(certificate);
         dest.writeString(fullyQualifiedDomainName);
         dest.writeByte((byte) (kcpEnabled ? 1 : 0));
+        dest.writeString(auth);
     }
 
     @Override
@@ -72,10 +79,14 @@ public class Introducer implements Parcelable {
         if (!"localhost".equals(fullyQualifiedDomainName) && fullyQualifiedDomainName.split("\\.").length < 2) {
             throw new IllegalArgumentException("Expected a FQDN, got: " + fullyQualifiedDomainName);
         }
+
+        if (auth == null || auth.isEmpty()) {
+            throw new IllegalArgumentException("Auth token is missing");
+        }
         return true;
     }
 
-    public static Introducer fromUrl(String introducerUrl) throws URISyntaxException {
+    public static Introducer fromUrl(String introducerUrl) throws URISyntaxException, IllegalArgumentException {
         URI uri = new URI(introducerUrl);
         String fqdn = getQueryParam(uri, "fqdn");
         if (fqdn == null || fqdn.isEmpty()) {
@@ -89,11 +100,15 @@ public class Introducer implements Parcelable {
             throw new IllegalArgumentException("Cert not found in the introducer URL");
         }
 
-        return new Introducer(uri.getScheme(), uri.getAuthority(), cert, fqdn, kcp);
+        String auth = getQueryParam(uri, "auth");
+        if (auth == null || auth.isEmpty()) {
+            throw new IllegalArgumentException("Authentication token not found in the introducer URL");
+        }
+        return new Introducer(uri.getScheme(), uri.getAuthority(), cert, fqdn, kcp, auth);
     }
 
-    public String toUrl() {
-        return String.format("%s://%s?fqdn=%s&kcp=%d&cert=%s", type, address, fullyQualifiedDomainName, kcpEnabled ? 1 : 0, certificate);
+    public String toUrl() throws UnsupportedEncodingException {
+        return String.format("%s://%s?fqdn=%s&kcp=%d&cert=%s&auth=%s", type, address, URLEncoder.encode(fullyQualifiedDomainName, "UTF-8"), kcpEnabled ? 1 : 0, URLEncoder.encode(certificate, "UTF-8"),  URLEncoder.encode(auth, "UTF-8"));
     }
 
     private static String getQueryParam(URI uri, String param) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
index b370f0f6284013cd5d68edf6014a69e33b73d319..79c6f5c407aa27e232c0e6f8ef4c348ef99c6c46 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
@@ -150,6 +150,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
             }
             return bm.getProvider();
         } catch (Exception e) {
+            e.printStackTrace();
             try {
                 if (allowRetry &&
                         TorStatusObservable.getStatus() == OFF &&
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java
index 3a75925e651f3561ef758315fbb381a336558f14..66b1dd0064e9a8fc169331e9ced8262066c54b12 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java
@@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModelProvider;
 import com.journeyapps.barcodescanner.ScanContract;
 import com.journeyapps.barcodescanner.ScanOptions;
 
+import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 
 import se.leap.bitmaskclient.R;
@@ -61,6 +62,7 @@ public class ProviderSelectionFragment extends BaseSetupFragment implements Canc
                             Introducer introducer = Introducer.fromUrl(result.getContents());
                             binding.editCustomProvider.setText(introducer.toUrl());
                         } catch (Exception e) {
+                            e.printStackTrace();
                             //binding.editCustomProvider.setText(result.getContents());
                         }
                     }
@@ -191,8 +193,12 @@ public class ProviderSelectionFragment extends BaseSetupFragment implements Canc
     public void providerSelectionChanged(){
         Provider provider = setupActivityCallback.getSelectedProvider();
         if (provider != null && provider.hasIntroducer()) {
-            binding.providerRadioGroup.check(INVITE_CODE_PROVIDER);
-            binding.editCustomProvider.setText(provider.getIntroducer().toUrl());
+            try {
+                binding.providerRadioGroup.check(INVITE_CODE_PROVIDER);
+                binding.editCustomProvider.setText(provider.getIntroducer().toUrl());
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
         } else {
             binding.providerRadioGroup.check(viewModel.getSelected());
         }