diff --git a/Luski.net/API.cs b/Luski.net/API.cs
index 951adbe..7cc78c5 100644
--- a/Luski.net/API.cs
+++ b/Luski.net/API.cs
@@ -15,24 +15,19 @@ public class API
     
     public async Task<PublicServer> GetPublicServer(string Domain, string Version = "v1", bool Secure = true)
     {
-        DateTime dt = DateTime.UtcNow;
-        Console.WriteLine("Connecting to public server '{0}' using API {1}.", Domain, Version);
         PublicServer s;
         try
         {
             IEnumerable<PublicServer> isl = InternalServers.Where(a => (a.Domain == Domain && a.ApiVersion == Version));
             if (isl.Any()) return isl.First();
-            s = new(Domain, Version, Secure)
-            {
-                ServerType = ServerType.Public
-            };
+            s = await PublicServer.GetServer(Domain, Version, Secure);
         }
         catch (Exception e)
         {
-            Console.WriteLine("Failed to connect to public server '{0}' using API {1}.", Domain, Version);
+            Console.WriteLine("Failed to connect to public server '{0}' using API {1}. No alternate server was found.", Domain, Version);
             throw;
         }
-        Console.WriteLine("Connected to public server '{0}' using API {1} in {4}.\nServer Name: {2}\nServer Description: {3}", Domain, Version, s.Name, s.Description, DateTime.UtcNow.Subtract(dt).ToString("g"));
+        
         string? f = s.Storage.GetStorageDirectory(StorageDirectory.StorageInfo) + "token";
         if (File.Exists(f))
         {
diff --git a/Luski.net/JsonTypes/LocalServerInfo.cs b/Luski.net/JsonTypes/LocalServerInfo.cs
new file mode 100644
index 0000000..8489c80
--- /dev/null
+++ b/Luski.net/JsonTypes/LocalServerInfo.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Text.Json.Serialization;
+
+namespace Luski.net.JsonTypes;
+
+public class LocalServerInfo
+{
+    [JsonInclude]
+    [JsonPropertyName("alternate_servers")]
+    public ServerData[] AlternateServers { get; set; } = Array.Empty<ServerData>();
+}
+
+[JsonSerializable(typeof(LocalServerInfo))]
+[JsonSourceGenerationOptions(
+    GenerationMode = JsonSourceGenerationMode.Default,
+    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
+    WriteIndented = false)]
+internal partial class LocalServerInfoContext : JsonSerializerContext
+{
+
+}
\ No newline at end of file
diff --git a/Luski.net/JsonTypes/ServerData.cs b/Luski.net/JsonTypes/ServerData.cs
new file mode 100644
index 0000000..3e25f0b
--- /dev/null
+++ b/Luski.net/JsonTypes/ServerData.cs
@@ -0,0 +1,23 @@
+using System.Text.Json.Serialization;
+
+namespace Luski.net.JsonTypes;
+
+public class ServerData
+{
+    [JsonInclude]
+    [JsonPropertyName("address")]
+    public string DomainAndPort = default!;
+    [JsonInclude]
+    [JsonPropertyName("secure")]
+    public bool Secure;
+}
+
+[JsonSerializable(typeof(ServerData))]
+[JsonSourceGenerationOptions(
+    GenerationMode = JsonSourceGenerationMode.Default,
+    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
+    WriteIndented = false)]
+internal partial class ServerDataContext : JsonSerializerContext
+{
+
+}
\ No newline at end of file
diff --git a/Luski.net/JsonTypes/ServerInfo.cs b/Luski.net/JsonTypes/ServerInfo.cs
index 04685a8..f341418 100644
--- a/Luski.net/JsonTypes/ServerInfo.cs
+++ b/Luski.net/JsonTypes/ServerInfo.cs
@@ -9,6 +9,10 @@ public class ServerInfo : IncomingHTTP
     public string wssv4 { get; set; }
     public string description { get; set; }
     public long owner { get; set; }
+    
+    [JsonInclude]
+    [JsonPropertyName("alternate_servers")]
+    public ServerData[] AlternateServers { get; set; } = default!;
 }
 
 [JsonSerializable(typeof(ServerInfo))]
diff --git a/Luski.net/Luski.net.csproj b/Luski.net/Luski.net.csproj
index a003ead..62ec8b5 100755
--- a/Luski.net/Luski.net.csproj
+++ b/Luski.net/Luski.net.csproj
@@ -13,7 +13,7 @@
     <RepositoryUrl>https://github.com/JacobTech-com/Luski.net</RepositoryUrl>
     <IncludeSymbols>True</IncludeSymbols>
     <FileVersion>1.0.0</FileVersion>
-    <Version>2.0.0-alpha12</Version>
+    <Version>2.0.0-alpha23</Version>
   </PropertyGroup>
 
   <ItemGroup>
diff --git a/Luski.net/PublicServer.cs b/Luski.net/PublicServer.cs
index fffe07a..1539d63 100644
--- a/Luski.net/PublicServer.cs
+++ b/Luski.net/PublicServer.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.Http;
 using System.Text;
 using System.Text.Json.Serialization.Metadata;
 using System.Threading;
@@ -29,14 +30,63 @@ public partial class PublicServer : Server
     public List<Role> roles { get; } = new();
 
     public SocketAppUser User { get; private set; } = null!;
-    
-    internal PublicServer(string Domain, string API_Version, bool Secure = true):
+
+    private PublicServer(string Domain, string API_Version, bool Secure = true) :
         base(Domain, API_Version, Secure)
+    { }
+
+    internal static async Task<PublicServer> GetServer(string Domain, string API_Version, bool Secure = true)
     {
-        ServerInfo si = GetFromServer("socketserver", ServerInfoContext.Default.ServerInfo, CancellationToken.None).Result;
-        Name = si.name;
-        Description = si.description;
-        wssurl = si.wssv4;
+        DateTime dt = DateTime.UtcNow;
+        Console.WriteLine("Connecting to public server '{0}' using API {1}.", Domain, API_Version);
+        PublicServer s = new(Domain, API_Version, Secure);
+        ServerInfo? si = null;
+        try
+        {
+            si = await s.GetFromServer("socketserver", ServerInfoContext.Default.ServerInfo, CancellationToken.None);
+            s.EncryptionHandler.ServerPublicKey = await (await new HttpClient()
+                .GetAsync($"{(s.Secure ? "https" : "http")}://{s.Domain}/{s.ApiVersion}/Keys/PublicKey"))
+                .Content
+                .ReadAsStringAsync();
+        }
+        catch (Exception e)
+        {
+            LocalServerInfo ServerListing = s.Storage.GetJson(StorageDirectory.ServerInfo, "Servers.json", true,
+                LocalServerInfoContext.Default.LocalServerInfo);
+            if (ServerListing.AlternateServers.Length > 0)
+            {
+                Console.WriteLine("Failed to connect to public server '{0}' using API {1}. Attempting to connect to alternate servers.", Domain, API_Version);
+                foreach (ServerData Server in ServerListing.AlternateServers)
+                {
+                    s.Secure = Server.Secure;
+                    s.Domain = Server.DomainAndPort;
+                    
+                    try
+                    {
+                        
+                        si = await s.GetFromServer("socketserver", ServerInfoContext.Default.ServerInfo, CancellationToken.None);
+                        s.EncryptionHandler.ServerPublicKey = await (await new HttpClient()
+                                .GetAsync($"{(s.Secure ? "https" : "http")}://{s.Domain}/{s.ApiVersion}/Keys/PublicKey"))
+                            .Content
+                            .ReadAsStringAsync();
+                        Console.WriteLine("Public server '{0}' connection restored by alternate server '{1}' using API {2}.", Domain, s.Domain, API_Version);
+                        break;
+                    }
+                    catch
+                    {
+                        // ignored
+                    }
+                }
+            }
+            
+            if (si is null) throw;
+        }
+        s.Name = si.name;
+        s.Description = si.description;
+        s.wssurl = si.wssv4;
+        s.ServerType = ServerType.Public;
+        Console.WriteLine("Connected to public server '{0}' using API {1} in {4}.\nServer Name: {2}\nServer Description: {3}", Domain, API_Version, s.Name, s.Description, DateTime.UtcNow.Subtract(dt).ToString("g"));
+        return s;
     }
     
     public async Task<TCategory> GetCategory<TCategory>(long id, CancellationToken CancellationToken) where TCategory : SocketCategory, new()
@@ -295,6 +345,6 @@ public partial class PublicServer : Server
         return Task.CompletedTask;
     }
     
-    public string Name { get; }
-    public string Description { get; }
+    public string Name { get; private set; }
+    public string Description { get; private set; }
 }
\ No newline at end of file
diff --git a/Luski.net/Server.Encryption.cs b/Luski.net/Server.Encryption.cs
index ef0820d..0cfa80c 100644
--- a/Luski.net/Server.Encryption.cs
+++ b/Luski.net/Server.Encryption.cs
@@ -12,12 +12,11 @@ public class ServerEncryption
 {
     internal bool Generating, Generated;
     internal string ServerPublicKey = "", MyPublicKey = "", myPrivateKey = "", OfflinePrivateKey = "", OfflinePublicKey = "";
+    
     internal byte[] Hash = default!;
-    internal ServerEncryption(string Domain, string API_Version, ServerStorage Storage, bool Secure)
+    internal ServerEncryption(ServerStorage Storage)
     {
         this.Storage = Storage;
-        ServerPublicKey = new HttpClient().GetAsync($"{(Secure ? "https" : "http" )}://{Domain}/{API_Version}/Keys/PublicKey").Result.Content
-            .ReadAsStringAsync().Result;
     }
 
     public string GetChannelKey(long Channel)
diff --git a/Luski.net/Server.Globals.cs b/Luski.net/Server.Globals.cs
index a39d109..27893e5 100644
--- a/Luski.net/Server.Globals.cs
+++ b/Luski.net/Server.Globals.cs
@@ -14,7 +14,7 @@ namespace Luski.net;
 public partial class Server
 {
     public ServerType ServerType { get; internal set; } = ServerType.Public;
-    public string Domain { get; } = default!;
+    public string Domain { get; set; } = default!;
     public string ApiVersion { get; } = "v1";
     internal WebSocket? ServerOut;
     internal  string? Token = null, Error = null, gen = null;
diff --git a/Luski.net/Server.Storage.cs b/Luski.net/Server.Storage.cs
index 80e079c..af191e4 100644
--- a/Luski.net/Server.Storage.cs
+++ b/Luski.net/Server.Storage.cs
@@ -4,6 +4,7 @@ using System.Linq;
 using System.Security.Cryptography;
 using System.Text;
 using System.Text.Json;
+using System.Text.Json.Serialization.Metadata;
 using JacobTechEncryption;
 using JacobTechEncryption.Enums;
 using Luski.net.Enums;
@@ -73,6 +74,20 @@ public class ServerStorage
     
     internal ServerStorageInfo RawInfo { get; }
 
+    public TResult GetJson<TResult>(StorageDirectory Directory, string Resource, bool CreateOnMissing, JsonTypeInfo<TResult> JsonInfo) where TResult : new()
+    {
+        string FilePath = GetResourceDirectory(Directory, Resource);
+        if (!File.Exists(FilePath))
+        {
+            TResult res = new();
+            File.WriteAllText(FilePath, JsonSerializer.Serialize(res, JsonInfo));
+            return res;
+        }
+        Stream s = GetResourceStream(FilePath);
+        return JsonSerializer.Deserialize(s, JsonInfo)!;
+    }
+    
+
     public byte[] UpdateStorage(byte[] OldPassword)
     {
         try
@@ -218,6 +233,11 @@ public class ServerStorage
         return Location + Directories[(byte)Directory] + "/";
     }
     
+    public string GetResourceDirectory(StorageDirectory Directory, string Resourse)
+    {
+        return Location + Directories[(byte)Directory] + "/" + Resourse;
+    }
+    
     public string GetResourceKey(StorageDirectory Directory, string Resource, string Key)
     {
         return Encoding.UTF8.GetString(Encryption.AES.Decrypt(GetResourceBytes(Directory, Resource), Key));
@@ -283,6 +303,23 @@ public class ServerStorage
         return ms;
     }
     
+    public Stream GetResourceStream(string dir)
+    {
+        byte[] buffer = new byte[16 * 1024];
+        MemoryStream ms = new();
+        using (FileStream r = File.OpenRead(dir))
+        {
+            int readBytes;
+            while ((readBytes = r.Read(buffer, 0, buffer.Length)) > 0)
+            {
+                ms.Write(buffer, 0, readBytes);
+            }
+        }
+
+        ms.Position = 0;
+        return ms;
+    }
+    
     public void SetResourceBytes(StorageDirectory Directory, string Resource, byte[] data)
     {
         File.WriteAllBytes(Location + Directories[(byte)Directory] + "/" + Resource, data);
diff --git a/Luski.net/Server.cs b/Luski.net/Server.cs
index 9f514ec..00ca01d 100644
--- a/Luski.net/Server.cs
+++ b/Luski.net/Server.cs
@@ -25,7 +25,7 @@ public partial class Server
         this.ApiVersion = API_Version;
         this.Secure = Secure;
         Storage = new(Domain);
-        EncryptionHandler = new(Domain, API_Version, Storage, this.Secure);
+        EncryptionHandler = new(Storage);
     }
 
     internal bool Secure = true;
diff --git a/Luski.net/Structures/Main/MainSocketUserBase.cs b/Luski.net/Structures/Main/MainSocketUserBase.cs
index 2892b77..bf3eb69 100644
--- a/Luski.net/Structures/Main/MainSocketUserBase.cs
+++ b/Luski.net/Structures/Main/MainSocketUserBase.cs
@@ -33,7 +33,6 @@ public class MainSocketUserBase : IncomingHTTP, IUser
     public Task<PublicKeyInfo[]> GetUserKeys(CancellationToken CancellationToken)
     {
         string data = Server.GetFromServer($"Keys/GetUserKey/{Id}", CancellationToken).Content.ReadAsStringAsync().Result;
-        //return Task.FromResult(new long[] {long.Parse(data)});
         return Task.FromResult(new[] { new PublicKeyInfo() { Id = long.Parse(data) }});
     }
 }