← Back to API Reference

Authentication Flow

Every SwiftAuth client follows the same flow. These examples show how to integrate SwiftAuth into your application using C++, C#, Go, Java, JavaScript, Kotlin, Lua, PHP, Python, Ruby, Rust, and Swift.

1
Initialize — Call /api/client/init with your app secret to get a session token.
2
Get Nonce — Call /api/client/nonce to get a one-time nonce (required for login, heartbeat, etc).
3
Login — Call /api/client/login with username/password, or /api/client/license with a license key.
4
Heartbeat — Call /api/client/heartbeat on a timer to keep the session alive.
5
Use API — Download files, fetch variables, etc. All calls require the session token.
Every mutation endpoint (login, heartbeat, license, etc.) requires a fresh nonce in the X-Nonce header. Call /api/client/nonce before each one.

Initialize Session

Start by calling POST /api/client/init with your application secret. You get back a sessionToken used for all subsequent calls.

import requests

BASE = "https://swiftauth.net/api"
APP_SECRET = "your-app-secret"

# 1. Initialize session
resp = requests.post(f"{BASE}/client/init", json={
    "secret": APP_SECRET,
    "version": "1.0.0",
    "hwid": "UNIQUE-HARDWARE-ID"
})
data = resp.json()["data"]
session_token = data["sessionToken"]
print(f"Session started: {data['appName']} v{data['appVersion']}")
const BASE = "https://swiftauth.net/api";
const APP_SECRET = "your-app-secret";

// 1. Initialize session
const initResp = await fetch(`${BASE}/client/init`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        secret: APP_SECRET,
        version: "1.0.0",
        hwid: "UNIQUE-HARDWARE-ID"
    })
});
const { data } = await initResp.json();
const sessionToken = data.sessionToken;
console.log(`Session started: ${data.appName} v${data.appVersion}`);
$base = "https://swiftauth.net/api";
$appSecret = "your-app-secret";

// 1. Initialize session
$resp = json_decode(file_get_contents("$base/client/init", false, stream_context_create([
    "http" => [
        "method" => "POST",
        "header" => "Content-Type: application/json",
        "content" => json_encode([
            "secret" => $appSecret,
            "version" => "1.0.0",
            "hwid" => "UNIQUE-HARDWARE-ID"
        ])
    ]
])));
$sessionToken = $resp->data->sessionToken;
echo "Session started: {$resp->data->appName} v{$resp->data->appVersion}\n";
using System.Net.Http;
using System.Text;
using System.Text.Json;

var baseUrl = "https://swiftauth.net/api";
var appSecret = "your-app-secret";
var http = new HttpClient();

// 1. Initialize session
var initResp = await http.PostAsync($"{baseUrl}/client/init",
    new StringContent(JsonSerializer.Serialize(new {
        secret = appSecret,
        version = "1.0.0",
        hwid = "UNIQUE-HARDWARE-ID"
    }), Encoding.UTF8, "application/json"));

var initJson = JsonDocument.Parse(await initResp.Content.ReadAsStringAsync());
var sessionToken = initJson.RootElement.GetProperty("data").GetProperty("sessionToken").GetString();
var appName = initJson.RootElement.GetProperty("data").GetProperty("appName").GetString();
Console.WriteLine($"Session started: {appName}");
// Requires libcurl and nlohmann/json
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <string>
#include <iostream>

using json = nlohmann::json;

const std::string BASE = "https://swiftauth.net/api";
const std::string APP_SECRET = "your-app-secret";

// Helper: POST JSON and return parsed response
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* out) {
    out->append((char*)contents, size * nmemb);
    return size * nmemb;
}

json post_json(const std::string& url, const json& body,
               const std::string& nonce = "") {
    CURL* curl = curl_easy_init();
    std::string response;

    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    if (!nonce.empty())
        headers = curl_slist_append(headers, ("X-Nonce: " + nonce).c_str());

    std::string payload = body.dump();
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    curl_easy_perform(curl);
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return json::parse(response);
}

int main() {
    curl_global_init(CURL_GLOBAL_DEFAULT);

    // 1. Initialize session
    auto init = post_json(BASE + "/client/init", {
        {"secret", APP_SECRET},
        {"version", "1.0.0"},
        {"hwid", "UNIQUE-HARDWARE-ID"}
    });
    std::string sessionToken = init["data"]["sessionToken"];
    std::cout << "Session started: "
              << init["data"]["appName"].get<std::string>() << std::endl;
package main

import (
    "fmt"
    "log"

    "github.com/swiftauth/swiftauth-go"
)

func main() {
    // 1. Initialize session
    client := swiftauth.NewClient(
        "https://swiftauth.net",
        "your-app-secret",
        "1.0.0",
        "UNIQUE-HARDWARE-ID",
    )

    _, err := client.Init()
    if err != nil {
        log.Fatalf("Init failed: %v", err)
    }
    fmt.Printf("Session started: %s v%s\n", client.App.Name, client.App.Version)
}
use swiftauth::SwiftAuthClient;

fn main() {
    // 1. Initialize session
    let mut client = SwiftAuthClient::new(
        "https://swiftauth.net",
        "your-app-secret",
        "1.0.0",
        Some("UNIQUE-HARDWARE-ID"),
    );

    client.init().expect("Init failed");
    let app = client.app.as_ref().unwrap();
    println!("Session started: {} v{}", app.name, app.version);
}
import net.swiftauth.SwiftAuthClient;
import net.swiftauth.SwiftAuthException;

public class Example {
    public static void main(String[] args) throws SwiftAuthException {
        // 1. Initialize session
        var client = new SwiftAuthClient(
            "https://swiftauth.net",
            "your-app-secret",
            "1.0.0",
            "UNIQUE-HARDWARE-ID"
        );

        client.init();
        System.out.printf("Session started: %s v%s%n",
            client.getApp().name(), client.getApp().version());
    }
}
import net.swiftauth.SwiftAuthClient

fun main() {
    // 1. Initialize session
    val client = SwiftAuthClient(
        baseUrl = "https://swiftauth.net",
        secret = "your-app-secret",
        version = "1.0.0",
        hwid = "UNIQUE-HARDWARE-ID"
    )

    client.init()
    println("Session started: ${client.app?.name} v${client.app?.version}")
}
require "swiftauth"

# 1. Initialize session
client = SwiftAuth::Client.new(
  base_url: "https://swiftauth.net",
  app_secret: "your-app-secret",
  app_version: "1.0.0",
  hwid: "UNIQUE-HARDWARE-ID"
)

client.init
puts "Session started: #{client.app.name} v#{client.app.version}"
import SwiftAuth

// 1. Initialize session
let client = SwiftAuthClient(
    baseURL: "https://swiftauth.net",
    appSecret: "your-app-secret",
    appVersion: "1.0.0",
    hwid: "UNIQUE-HARDWARE-ID"
)

try client.initialize()
print("Session started: \(client.app!.name) v\(client.app!.version)")
local SwiftAuth = require("swiftauth")

-- 1. Initialize session
local client = SwiftAuth.new(
    "https://swiftauth.net",
    "your-app-secret",
    "1.0.0",
    "UNIQUE-HARDWARE-ID"
)

client:init()
print("Session started: " .. client.app.name .. " v" .. client.app.version)

Login with Username & Password

After initializing, get a nonce then call POST /api/client/login. The nonce goes in the X-Nonce header.

# 2. Get a nonce
nonce_resp = requests.post(f"{BASE}/client/nonce", json={
    "sessionToken": session_token
})
nonce = nonce_resp.json()["data"]["nonce"]

# 3. Login with username/password
login_resp = requests.post(f"{BASE}/client/login",
    headers={"X-Nonce": nonce},
    json={
        "sessionToken": session_token,
        "username": "myuser",
        "password": "mypassword",
        "hwid": "UNIQUE-HARDWARE-ID"
    }
)
user = login_resp.json()["data"]
print(f"Logged in as {user['username']} (level {user['level']})")
// 2. Get a nonce
const nonceResp = await fetch(`${BASE}/client/nonce`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken })
});
const nonce = (await nonceResp.json()).data.nonce;

// 3. Login with username/password
const loginResp = await fetch(`${BASE}/client/login`, {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-Nonce": nonce
    },
    body: JSON.stringify({
        sessionToken,
        username: "myuser",
        password: "mypassword",
        hwid: "UNIQUE-HARDWARE-ID"
    })
});
const user = (await loginResp.json()).data;
console.log(`Logged in as ${user.username} (level ${user.level})`);
// Helper function for POST requests
function swiftPost($url, $data, $nonce = null) {
    $headers = "Content-Type: application/json\r\n";
    if ($nonce) $headers .= "X-Nonce: $nonce\r\n";
    return json_decode(file_get_contents($url, false, stream_context_create([
        "http" => [
            "method" => "POST",
            "header" => $headers,
            "content" => json_encode($data)
        ]
    ])));
}

// 2. Get a nonce
$nonceResp = swiftPost("$base/client/nonce", [
    "sessionToken" => $sessionToken
]);
$nonce = $nonceResp->data->nonce;

// 3. Login with username/password
$loginResp = swiftPost("$base/client/login", [
    "sessionToken" => $sessionToken,
    "username" => "myuser",
    "password" => "mypassword",
    "hwid" => "UNIQUE-HARDWARE-ID"
], $nonce);
$user = $loginResp->data;
echo "Logged in as {$user->username} (level {$user->level})\n";
// Helper: POST with optional nonce
async Task<JsonDocument> SwiftPost(string url, object body, string? nonce = null) {
    var request = new HttpRequestMessage(HttpMethod.Post, url);
    request.Content = new StringContent(
        JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
    if (nonce != null) request.Headers.Add("X-Nonce", nonce);
    var resp = await http.SendAsync(request);
    return JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
}

// 2. Get a nonce
var nonceJson = await SwiftPost($"{baseUrl}/client/nonce",
    new { sessionToken });
var nonce = nonceJson.RootElement.GetProperty("data").GetProperty("nonce").GetString();

// 3. Login with username/password
var loginJson = await SwiftPost($"{baseUrl}/client/login", new {
    sessionToken,
    username = "myuser",
    password = "mypassword",
    hwid = "UNIQUE-HARDWARE-ID"
}, nonce);
var userData = loginJson.RootElement.GetProperty("data");
Console.WriteLine($"Logged in as {userData.GetProperty("username")} (level {userData.GetProperty("level")})");
    // Helper: get a fresh nonce
    auto get_nonce = [&]() -> std::string {
        auto resp = post_json(BASE + "/client/nonce", {
            {"sessionToken", sessionToken}
        });
        return resp["data"]["nonce"];
    };

    // 2-3. Login with username/password
    std::string nonce = get_nonce();
    auto login = post_json(BASE + "/client/login", {
        {"sessionToken", sessionToken},
        {"username", "myuser"},
        {"password", "mypassword"},
        {"hwid", "UNIQUE-HARDWARE-ID"}
    }, nonce);

    std::cout << "Logged in as "
              << login["data"]["username"].get<std::string>()
              << " (level " << login["data"]["level"] << ")" << std::endl;
    // 2-3. Login with username/password (nonce is fetched automatically)
    _, err = client.Login("myuser", "mypassword", "", "")
    if err != nil {
        log.Fatalf("Login failed: %v", err)
    }
    fmt.Printf("Logged in as %s (level %d)\n", client.User.Username, client.User.Level)
    // 2-3. Login with username/password (nonce is fetched automatically)
    client.login("myuser", "mypassword", None, "")
        .expect("Login failed");
    let user = client.user.as_ref().unwrap();
    println!("Logged in as {} (level {})", user.username, user.level);
        // 2-3. Login with username/password (nonce is fetched automatically)
        client.login("myuser", "mypassword");
        System.out.printf("Logged in as %s (level %d)%n",
            client.getUser().username(), client.getUser().level());
    // 2-3. Login with username/password (nonce is fetched automatically)
    client.login("myuser", "mypassword")
    println("Logged in as ${client.user?.username} (level ${client.user?.level})")
# 2-3. Login with username/password (nonce is fetched automatically)
client.login("myuser", "mypassword")
puts "Logged in as #{client.user.username} (level #{client.user.level})"
// 2-3. Login with username/password (nonce is fetched automatically)
try client.login(username: "myuser", password: "mypassword")
print("Logged in as \(client.user!.username) (level \(client.user!.level))")
-- 2-3. Login with username/password (nonce is fetched automatically)
client:login("myuser", "mypassword")
print("Logged in as " .. client.user.username .. " (level " .. client.user.level .. ")")

Login with License Key

Use POST /api/client/license for license-only authentication. No username or password needed.

# Get a fresh nonce first
nonce_resp = requests.post(f"{BASE}/client/nonce", json={
    "sessionToken": session_token
})
nonce = nonce_resp.json()["data"]["nonce"]

# Login with license key only
license_resp = requests.post(f"{BASE}/client/license",
    headers={"X-Nonce": nonce},
    json={
        "sessionToken": session_token,
        "licenseKey": "XXXXX-XXXXX-XXXXX-XXXXX",
        "hwid": "UNIQUE-HARDWARE-ID"
    }
)
user = license_resp.json()["data"]
print(f"Licensed as {user['username']} (level {user['level']}, expires {user['expiresAt']})")
// Get a fresh nonce
const licNonceResp = await fetch(`${BASE}/client/nonce`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken })
});
const licNonce = (await licNonceResp.json()).data.nonce;

// Login with license key only
const licResp = await fetch(`${BASE}/client/license`, {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-Nonce": licNonce
    },
    body: JSON.stringify({
        sessionToken,
        licenseKey: "XXXXX-XXXXX-XXXXX-XXXXX",
        hwid: "UNIQUE-HARDWARE-ID"
    })
});
const licUser = (await licResp.json()).data;
console.log(`Licensed as ${licUser.username} (level ${licUser.level})`);
// Get a fresh nonce
$nonce = swiftPost("$base/client/nonce", [
    "sessionToken" => $sessionToken
])->data->nonce;

// Login with license key only
$licResp = swiftPost("$base/client/license", [
    "sessionToken" => $sessionToken,
    "licenseKey" => "XXXXX-XXXXX-XXXXX-XXXXX",
    "hwid" => "UNIQUE-HARDWARE-ID"
], $nonce);
$user = $licResp->data;
echo "Licensed as {$user->username} (level {$user->level})\n";
// Get a fresh nonce
var licNonceJson = await SwiftPost($"{baseUrl}/client/nonce",
    new { sessionToken });
var licNonce = licNonceJson.RootElement.GetProperty("data").GetProperty("nonce").GetString();

// Login with license key only
var licJson = await SwiftPost($"{baseUrl}/client/license", new {
    sessionToken,
    licenseKey = "XXXXX-XXXXX-XXXXX-XXXXX",
    hwid = "UNIQUE-HARDWARE-ID"
}, licNonce);
var licData = licJson.RootElement.GetProperty("data");
Console.WriteLine($"Licensed as {licData.GetProperty("username")} (level {licData.GetProperty("level")})");
    // Login with license key only
    nonce = get_nonce();
    auto lic = post_json(BASE + "/client/license", {
        {"sessionToken", sessionToken},
        {"licenseKey", "XXXXX-XXXXX-XXXXX-XXXXX"},
        {"hwid", "UNIQUE-HARDWARE-ID"}
    }, nonce);

    std::cout << "Licensed as "
              << lic["data"]["username"].get<std::string>()
              << " (level " << lic["data"]["level"] << ")" << std::endl;
    // Login with license key only (nonce is fetched automatically)
    _, err = client.LicenseLogin("XXXXX-XXXXX-XXXXX-XXXXX", "")
    if err != nil {
        log.Fatalf("License login failed: %v", err)
    }
    fmt.Printf("Licensed as %s (level %d, expires %s)\n",
        client.User.Key, client.User.Level, client.User.ExpiresAt)
    // Login with license key only (nonce is fetched automatically)
    client.license_login("XXXXX-XXXXX-XXXXX-XXXXX", "")
        .expect("License login failed");
    let user = client.user.as_ref().unwrap();
    println!("Licensed as {} (level {}, expires {})",
        user.key, user.level, user.expires_at.as_deref().unwrap_or("Never"));
        // Login with license key only (nonce is fetched automatically)
        client.licenseLogin("XXXXX-XXXXX-XXXXX-XXXXX");
        System.out.printf("Licensed as %s (level %d, expires %s)%n",
            client.getUser().key(), client.getUser().level(),
            client.getUser().expiresAt());
    // Login with license key only (nonce is fetched automatically)
    client.licenseLogin("XXXXX-XXXXX-XXXXX-XXXXX")
    println("Licensed as ${client.user?.key} (level ${client.user?.level}, expires ${client.user?.expiresAt})")
# Login with license key only (nonce is fetched automatically)
client.license_login("XXXXX-XXXXX-XXXXX-XXXXX")
puts "Licensed as #{client.user.key} (level #{client.user.level}, expires #{client.user.expires_at})"
// Login with license key only (nonce is fetched automatically)
try client.licenseLogin(licenseKey: "XXXXX-XXXXX-XXXXX-XXXXX")
print("Licensed as \(client.user!.key) (level \(client.user!.level), expires \(client.user!.expiresAt ?? "Never"))")
-- Login with license key only (nonce is fetched automatically)
client:license_login("XXXXX-XXXXX-XXXXX-XXXXX")
print("Licensed as " .. client.user.key .. " (level " .. client.user.level .. ", expires " .. (client.user.expires_at or "Never") .. ")")

Heartbeat (Keep Session Alive)

Call POST /api/client/heartbeat on a timer to prevent the session from expiring. Each heartbeat requires a fresh nonce. Run this in a background thread/interval.

If you stop sending heartbeats, the session will expire and the user will need to re-authenticate. Recommended interval: every 30 seconds.
import threading
import time

def heartbeat_loop(session_token):
    while True:
        try:
            # Get fresh nonce
            nonce = requests.post(f"{BASE}/client/nonce", json={
                "sessionToken": session_token
            }).json()["data"]["nonce"]

            # Send heartbeat
            resp = requests.post(f"{BASE}/client/heartbeat",
                headers={"X-Nonce": nonce},
                json={"sessionToken": session_token}
            )
            if not resp.json().get("success"):
                print("Heartbeat failed — session expired")
                break
        except Exception as e:
            print(f"Heartbeat error: {e}")
        time.sleep(30)

# Start heartbeat in background
hb_thread = threading.Thread(target=heartbeat_loop, args=(session_token,), daemon=True)
hb_thread.start()
// Heartbeat loop — runs every 30 seconds
const heartbeatInterval = setInterval(async () => {
    try {
        // Get fresh nonce
        const nResp = await fetch(`${BASE}/client/nonce`, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ sessionToken })
        });
        const n = (await nResp.json()).data.nonce;

        // Send heartbeat
        const hbResp = await fetch(`${BASE}/client/heartbeat`, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "X-Nonce": n
            },
            body: JSON.stringify({ sessionToken })
        });
        const hb = await hbResp.json();
        if (!hb.success) {
            console.error("Heartbeat failed — session expired");
            clearInterval(heartbeatInterval);
        }
    } catch (err) {
        console.error("Heartbeat error:", err);
    }
}, 30000);
// PHP heartbeat (for long-running CLI scripts)
function sendHeartbeat($base, $sessionToken) {
    $nonce = swiftPost("$base/client/nonce", [
        "sessionToken" => $sessionToken
    ])->data->nonce;

    $resp = swiftPost("$base/client/heartbeat", [
        "sessionToken" => $sessionToken
    ], $nonce);

    return $resp->success ?? false;
}

// Run heartbeat in a loop
while (true) {
    if (!sendHeartbeat($base, $sessionToken)) {
        echo "Heartbeat failed — session expired\n";
        break;
    }
    sleep(30);
}
// Heartbeat with a background timer
var heartbeatCts = new CancellationTokenSource();

_ = Task.Run(async () => {
    while (!heartbeatCts.Token.IsCancellationRequested) {
        try {
            // Get fresh nonce
            var nJson = await SwiftPost($"{baseUrl}/client/nonce",
                new { sessionToken });
            var n = nJson.RootElement.GetProperty("data").GetProperty("nonce").GetString();

            // Send heartbeat
            var hbJson = await SwiftPost($"{baseUrl}/client/heartbeat",
                new { sessionToken }, n);
            if (!hbJson.RootElement.GetProperty("success").GetBoolean()) {
                Console.WriteLine("Heartbeat failed — session expired");
                break;
            }
        } catch (Exception ex) {
            Console.WriteLine($"Heartbeat error: {ex.Message}");
        }
        await Task.Delay(30000, heartbeatCts.Token);
    }
});
    // Heartbeat in a background thread
    std::thread heartbeat_thread([&]() {
        while (true) {
            try {
                std::string n = get_nonce();
                auto hb = post_json(BASE + "/client/heartbeat", {
                    {"sessionToken", sessionToken}
                }, n);
                if (!hb.value("success", false)) {
                    std::cerr << "Heartbeat failed — session expired" << std::endl;
                    break;
                }
            } catch (const std::exception& e) {
                std::cerr << "Heartbeat error: " << e.what() << std::endl;
            }
            std::this_thread::sleep_for(std::chrono::seconds(30));
        }
    });
    heartbeat_thread.detach();
    // Heartbeat in a background goroutine — runs every 30 seconds
    go func() {
        for {
            _, err := client.Heartbeat()
            if err != nil {
                fmt.Printf("Heartbeat failed — session expired: %v\n", err)
                return
            }
            time.Sleep(30 * time.Second)
        }
    }()
    // Heartbeat (single call — wrap in a loop/thread for continuous use)
    match client.heartbeat() {
        Ok(hb) => {
            let exp = hb.get("expiresAt")
                .and_then(|v| v.as_str())
                .unwrap_or("unknown");
            println!("Heartbeat OK — session alive until {}", exp);
        }
        Err(e) => eprintln!("Heartbeat failed: {}", e),
    }

    // For continuous heartbeat, spawn a thread:
    // std::thread::spawn(move || loop {
    //     client.heartbeat().ok();
    //     std::thread::sleep(std::time::Duration::from_secs(30));
    // });
        // Heartbeat in a background thread — runs every 30 seconds
        Thread heartbeatThread = new Thread(() -> {
            while (true) {
                try {
                    client.heartbeat();
                } catch (SwiftAuthException e) {
                    System.err.println("Heartbeat failed — session expired: " + e.getMessage());
                    break;
                }
                try { Thread.sleep(30000); } catch (InterruptedException ignored) { break; }
            }
        });
        heartbeatThread.setDaemon(true);
        heartbeatThread.start();
    // Heartbeat in a background thread — runs every 30 seconds
    val heartbeatThread = thread(isDaemon = true) {
        while (true) {
            try {
                client.heartbeat()
            } catch (e: SwiftAuthException) {
                println("Heartbeat failed — session expired: ${e.message}")
                break
            }
            Thread.sleep(30000)
        }
    }
# Heartbeat in a background thread — runs every 30 seconds
heartbeat_thread = Thread.new do
  loop do
    begin
      client.heartbeat
    rescue SwiftAuth::Error => e
      puts "Heartbeat failed — session expired: #{e.message}"
      break
    end
    sleep 30
  end
end
// Heartbeat in a background queue — runs every 30 seconds
let heartbeatQueue = DispatchQueue(label: "heartbeat", qos: .background)
heartbeatQueue.async {
    while true {
        do {
            let hb = try client.heartbeat()
            print("Heartbeat OK — session alive until \(hb["expiresAt"] as? String ?? "unknown")")
        } catch {
            print("Heartbeat failed — session expired: \(error)")
            break
        }
        Thread.sleep(forTimeInterval: 30)
    }
}
-- Heartbeat (single call — use a timer/coroutine for continuous use)
local ok, hb_err = pcall(function()
    local hb = client:heartbeat()
    print("Heartbeat OK — session alive until " .. (hb.expiresAt or "unknown"))
end)
if not ok then
    print("Heartbeat failed: " .. tostring(hb_err))
end

-- For continuous heartbeat in a coroutine or timer:
-- while true do
--     client:heartbeat()
--     os.execute("sleep 30")  -- or use a non-blocking timer
-- end

Download a File

After authenticating, call POST /api/client/file with the file name. The response is the raw file bytes. The file hash and version are returned in response headers.

# Download a file
file_resp = requests.post(f"{BASE}/client/file", json={
    "sessionToken": session_token,
    "name": "loader.dll"
})
if file_resp.status_code == 200:
    file_hash = file_resp.headers.get("X-File-Hash")
    file_version = file_resp.headers.get("X-File-Version")
    with open("loader.dll", "wb") as f:
        f.write(file_resp.content)
    print(f"Downloaded loader.dll (hash: {file_hash}, version: {file_version})")
// Download a file (Node.js)
import fs from "fs";

const fileResp = await fetch(`${BASE}/client/file`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        sessionToken,
        name: "loader.dll"
    })
});
if (fileResp.ok) {
    const fileHash = fileResp.headers.get("X-File-Hash");
    const fileVersion = fileResp.headers.get("X-File-Version");
    const buffer = Buffer.from(await fileResp.arrayBuffer());
    fs.writeFileSync("loader.dll", buffer);
    console.log(`Downloaded loader.dll (hash: ${fileHash}, version: ${fileVersion})`);
}
// Download a file
$ch = curl_init("$base/client/file");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS => json_encode([
        "sessionToken" => $sessionToken,
        "name" => "loader.dll"
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER => true
]);
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
curl_close($ch);

file_put_contents("loader.dll", $body);
echo "Downloaded loader.dll\n";
// Download a file
var fileReq = new HttpRequestMessage(HttpMethod.Post, $"{baseUrl}/client/file");
fileReq.Content = new StringContent(
    JsonSerializer.Serialize(new { sessionToken, name = "loader.dll" }),
    Encoding.UTF8, "application/json");
var fileResp = await http.SendAsync(fileReq);

if (fileResp.IsSuccessStatusCode) {
    var fileHash = fileResp.Headers.GetValues("X-File-Hash").FirstOrDefault();
    var fileVersion = fileResp.Headers.GetValues("X-File-Version").FirstOrDefault();
    var bytes = await fileResp.Content.ReadAsByteArrayAsync();
    await File.WriteAllBytesAsync("loader.dll", bytes);
    Console.WriteLine($"Downloaded loader.dll (hash: {fileHash}, version: {fileVersion})");
}
    // Download a file
    CURL* dl = curl_easy_init();
    FILE* fp = fopen("loader.dll", "wb");
    json dl_body = {{"sessionToken", sessionToken}, {"name", "loader.dll"}};
    std::string dl_payload = dl_body.dump();

    struct curl_slist* dl_headers = nullptr;
    dl_headers = curl_slist_append(dl_headers, "Content-Type: application/json");

    curl_easy_setopt(dl, CURLOPT_URL, (BASE + "/client/file").c_str());
    curl_easy_setopt(dl, CURLOPT_POSTFIELDS, dl_payload.c_str());
    curl_easy_setopt(dl, CURLOPT_HTTPHEADER, dl_headers);
    curl_easy_setopt(dl, CURLOPT_WRITEDATA, fp);
    curl_easy_perform(dl);
    curl_slist_free_all(dl_headers);
    curl_easy_cleanup(dl);
    fclose(fp);
    std::cout << "Downloaded loader.dll" << std::endl;
    // Download a file
    fileData, err := client.DownloadFile("loader.dll")
    if err != nil {
        log.Fatalf("Download failed: %v", err)
    }
    err = os.WriteFile("loader.dll", fileData, 0644)
    if err != nil {
        log.Fatalf("Write failed: %v", err)
    }
    fmt.Printf("Downloaded loader.dll (%d bytes)\n", len(fileData))
    // Download a file
    let file_data = client.download_file("loader.dll")
        .expect("Download failed");
    std::fs::write("loader.dll", &file_data)
        .expect("Failed to write file");
    println!("Downloaded loader.dll ({} bytes)", file_data.len());
        // Download a file
        byte[] fileData = client.downloadFile("loader.dll");
        java.nio.file.Files.write(
            java.nio.file.Path.of("loader.dll"), fileData);
        System.out.printf("Downloaded loader.dll (%d bytes)%n", fileData.length);
    // Download a file
    val fileData = client.downloadFile("loader.dll")
    java.io.File("loader.dll").writeBytes(fileData)
    println("Downloaded loader.dll (${fileData.size} bytes)")
# Download a file
file_data = client.download_file("loader.dll")
File.binwrite("loader.dll", file_data)
puts "Downloaded loader.dll (#{file_data.bytesize} bytes)"
// Download a file
let fileData = try client.downloadFile(name: "loader.dll")
try fileData.write(to: URL(fileURLWithPath: "loader.dll"))
print("Downloaded loader.dll (\(fileData.count) bytes)")
-- Download a file
local file_data = client:download_file("loader.dll")
local f = io.open("loader.dll", "wb")
f:write(file_data)
f:close()
print("Downloaded loader.dll (" .. #file_data .. " bytes)")

Get Variables

Fetch app variables with POST /api/client/variables (all) or POST /api/client/variable (single by name).

# Get all variables
vars_resp = requests.post(f"{BASE}/client/variables", json={
    "sessionToken": session_token
})
variables = vars_resp.json()["data"]["variables"]
for v in variables:
    print(f"  {v['name']} = {v['value']}")

# Get a single variable
var_resp = requests.post(f"{BASE}/client/variable", json={
    "sessionToken": session_token,
    "name": "api_endpoint"
})
print(f"api_endpoint = {var_resp.json()['data']['value']}")
// Get all variables
const varsResp = await fetch(`${BASE}/client/variables`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken })
});
const variables = (await varsResp.json()).data.variables;
variables.forEach(v => console.log(`  ${v.name} = ${v.value}`));

// Get a single variable
const varResp = await fetch(`${BASE}/client/variable`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken, name: "api_endpoint" })
});
console.log(`api_endpoint = ${(await varResp.json()).data.value}`);
// Get all variables
$varsResp = swiftPost("$base/client/variables", [
    "sessionToken" => $sessionToken
]);
foreach ($varsResp->data->variables as $v) {
    echo "  {$v->name} = {$v->value}\n";
}

// Get a single variable
$varResp = swiftPost("$base/client/variable", [
    "sessionToken" => $sessionToken,
    "name" => "api_endpoint"
]);
echo "api_endpoint = {$varResp->data->value}\n";
// Get all variables
var varsJson = await SwiftPost($"{baseUrl}/client/variables",
    new { sessionToken });
var vars = varsJson.RootElement.GetProperty("data").GetProperty("variables");
foreach (var v in vars.EnumerateArray()) {
    Console.WriteLine($"  {v.GetProperty("name")} = {v.GetProperty("value")}");
}

// Get a single variable
var varJson = await SwiftPost($"{baseUrl}/client/variable",
    new { sessionToken, name = "api_endpoint" });
Console.WriteLine($"api_endpoint = {varJson.RootElement.GetProperty("data").GetProperty("value")}");
    // Get all variables
    auto vars = post_json(BASE + "/client/variables", {
        {"sessionToken", sessionToken}
    });
    for (auto& v : vars["data"]["variables"]) {
        std::cout << "  " << v["name"].get<std::string>()
                  << " = " << v["value"].get<std::string>() << std::endl;
    }

    // Get a single variable
    auto var_resp = post_json(BASE + "/client/variable", {
        {"sessionToken", sessionToken},
        {"name", "api_endpoint"}
    });
    std::cout << "api_endpoint = "
              << var_resp["data"]["value"].get<std::string>() << std::endl;
    // Get all variables
    vars, err := client.GetAllVariables()
    if err != nil {
        log.Fatalf("Failed to get variables: %v", err)
    }
    for _, v := range vars {
        fmt.Printf("  %s = %s\n", v.Key, v.Value)
    }

    // Get a single variable
    v, err := client.GetVariable("api_endpoint")
    if err != nil {
        log.Fatalf("Failed to get variable: %v", err)
    }
    fmt.Printf("api_endpoint = %s\n", v.Value)
    // Get all variables
    let vars = client.get_all_variables()
        .expect("Failed to get variables");
    for v in &vars {
        println!("  {} = {}", v.key, v.value);
    }

    // Get a single variable
    let v = client.get_variable("api_endpoint")
        .expect("Failed to get variable");
    println!("api_endpoint = {}", v.value);
        // Get all variables
        Map<String, Object> varsData = client.getAllVariables();
        Object list = varsData.get("_list");
        if (list instanceof List<?> varList) {
            for (Object item : varList) {
                if (item instanceof Map<?,?> v) {
                    System.out.printf("  %s = %s%n", v.get("key"), v.get("value"));
                }
            }
        }

        // Get a single variable
        Map<String, Object> varData = client.getVariable("api_endpoint");
        System.out.printf("api_endpoint = %s%n", varData.get("value"));
    // Get all variables
    val vars = client.getAllVariables()
    for (v in vars) {
        println("  ${v.key} = ${v.value}")
    }

    // Get a single variable
    val v = client.getVariable("api_endpoint")
    println("api_endpoint = ${v.value}")
# Get all variables
vars = client.get_all_variables
vars.each { |v| puts "  #{v.key} = #{v.value}" }

# Get a single variable
v = client.get_variable("api_endpoint")
puts "api_endpoint = #{v.value}"
// Get all variables
let vars = try client.getAllVariables()
for v in vars {
    print("  \(v.key) = \(v.value)")
}

// Get a single variable
let v = try client.getVariable(key: "api_endpoint")
print("api_endpoint = \(v.value)")
-- Get all variables
local vars = client:get_all_variables()
for _, v in ipairs(vars) do
    print("  " .. v.key .. " = " .. v.value)
end

-- Get a single variable
local v = client:get_variable("api_endpoint")
print("api_endpoint = " .. v.value)

License Variables

Fetch per-key variables attached to the user's active license with POST /api/client/license-variables (all) or POST /api/client/license-variable (single by key). Requires a Pro+ plan.

# Get all license variables
resp = requests.post(f"{BASE}/client/license-variables", json={
    "sessionToken": session_token
})
for v in resp.json()["data"]:
    print(f"  {v['key']} ({v['type']}) = {v['value']}")

# Get a single license variable
resp = requests.post(f"{BASE}/client/license-variable", json={
    "sessionToken": session_token,
    "key": "max_seats"
})
print(f"max_seats = {resp.json()['data']['value']}")
// Get all license variables
const licVarsResp = await fetch(`${BASE}/client/license-variables`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken })
});
const licVars = (await licVarsResp.json()).data;
licVars.forEach(v => console.log(`  ${v.key} (${v.type}) = ${v.value}`));

// Get a single license variable
const licVarResp = await fetch(`${BASE}/client/license-variable`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken, key: "max_seats" })
});
console.log(`max_seats = ${(await licVarResp.json()).data.value}`);
// Get all license variables
$licVarsResp = swiftPost("$base/client/license-variables", [
    "sessionToken" => $sessionToken
]);
foreach ($licVarsResp->data as $v) {
    echo "  {$v->key} ({$v->type}) = {$v->value}\n";
}

// Get a single license variable
$licVarResp = swiftPost("$base/client/license-variable", [
    "sessionToken" => $sessionToken,
    "key" => "max_seats"
]);
echo "max_seats = {$licVarResp->data->value}\n";
// Get all license variables
var licVarsJson = await SwiftPost($"{baseUrl}/client/license-variables",
    new { sessionToken });
foreach (var v in licVarsJson.RootElement.GetProperty("data").EnumerateArray()) {
    Console.WriteLine($"  {v.GetProperty("key")} ({v.GetProperty("type")}) = {v.GetProperty("value")}");
}

// Get a single license variable
var licVarJson = await SwiftPost($"{baseUrl}/client/license-variable",
    new { sessionToken, key = "max_seats" });
Console.WriteLine($"max_seats = {licVarJson.RootElement.GetProperty("data").GetProperty("value")}");
    // Get all license variables
    auto lic_vars = post_json(BASE + "/client/license-variables", {
        {"sessionToken", sessionToken}
    });
    for (auto& v : lic_vars["data"]) {
        std::cout << "  " << v["key"].get<std::string>()
                  << " (" << v["type"].get<std::string>() << ") = "
                  << v["value"].get<std::string>() << std::endl;
    }

    // Get a single license variable
    auto lic_var = post_json(BASE + "/client/license-variable", {
        {"sessionToken", sessionToken},
        {"key", "max_seats"}
    });
    std::cout << "max_seats = "
              << lic_var["data"]["value"].get<std::string>() << std::endl;
    // Get all license variables — uses raw API since SDK wraps it
    licVarsResp, err := client.PostJSON("/client/license-variables", map[string]any{})
    if err != nil {
        log.Fatalf("Failed to get license variables: %v", err)
    }
    if data, ok := licVarsResp["data"].([]any); ok {
        for _, item := range data {
            if v, ok := item.(map[string]any); ok {
                fmt.Printf("  %s (%s) = %s\n", v["key"], v["type"], v["value"])
            }
        }
    }

    // Get a single license variable
    licVarResp, err := client.PostJSON("/client/license-variable", map[string]any{
        "key": "max_seats",
    })
    if err != nil {
        log.Fatalf("Failed to get license variable: %v", err)
    }
    if data, ok := licVarResp["data"].(map[string]any); ok {
        fmt.Printf("max_seats = %s\n", data["value"])
    }
    // Get all license variables — uses raw API post
    let lic_vars_resp = client.post_json("/client/license-variables",
        &serde_json::json!({}))
        .expect("Failed to get license variables");
    if let Some(data) = lic_vars_resp["data"].as_array() {
        for v in data {
            println!("  {} ({}) = {}",
                v["key"].as_str().unwrap_or(""),
                v["type"].as_str().unwrap_or(""),
                v["value"].as_str().unwrap_or(""));
        }
    }

    // Get a single license variable
    let lic_var_resp = client.post_json("/client/license-variable",
        &serde_json::json!({"key": "max_seats"}))
        .expect("Failed to get license variable");
    println!("max_seats = {}",
        lic_var_resp["data"]["value"].as_str().unwrap_or(""));
        // Get all license variables — uses raw API post
        var licVarsResp = client.post("/client/license-variables",
            Map.of());
        if (licVarsResp.get("data") instanceof List<?> licVarList) {
            for (Object item : licVarList) {
                if (item instanceof Map<?,?> v) {
                    System.out.printf("  %s (%s) = %s%n",
                        v.get("key"), v.get("type"), v.get("value"));
                }
            }
        }

        // Get a single license variable
        var licVarResp = client.post("/client/license-variable",
            Map.of("key", "max_seats"));
        if (licVarResp.get("data") instanceof Map<?,?> lvData) {
            System.out.printf("max_seats = %s%n", lvData.get("value"));
        }
    // Get all license variables — uses raw API post
    val licVarsResp = client.post("/client/license-variables", emptyMap())
    val licVarList = licVarsResp["data"] as? List<*>
    licVarList?.forEach { item ->
        val v = item as? Map<*, *>
        if (v != null) {
            println("  ${v["key"]} (${v["type"]}) = ${v["value"]}")
        }
    }

    // Get a single license variable
    val licVarResp = client.post("/client/license-variable",
        mapOf("key" to "max_seats"))
    val lvData = licVarResp["data"] as? Map<*, *>
    println("max_seats = ${lvData?.get("value")}")
# Get all license variables — uses raw API post
lic_vars_resp = client.post("/client/license-variables", {})
lic_vars_resp["data"].each do |v|
  puts "  #{v["key"]} (#{v["type"]}) = #{v["value"]}"
end

# Get a single license variable
lic_var_resp = client.post("/client/license-variable", { key: "max_seats" })
puts "max_seats = #{lic_var_resp["data"]["value"]}"
// Get all license variables — uses raw API post
let licVarsResp = try client.post(path: "/client/license-variables", body: [:])
if let data = licVarsResp["data"] as? [[String: Any]] {
    for v in data {
        print("  \(v["key"] ?? "") (\(v["type"] ?? "")) = \(v["value"] ?? "")")
    }
}

// Get a single license variable
let licVarResp = try client.post(path: "/client/license-variable",
    body: ["key": "max_seats"])
if let data = licVarResp["data"] as? [String: Any] {
    print("max_seats = \(data["value"] ?? "")")
}
-- Get all license variables — uses raw API post
local lic_vars_resp = client:post("/client/license-variables", {})
if type(lic_vars_resp.data) == "table" then
    for _, v in ipairs(lic_vars_resp.data) do
        print("  " .. (v.key or "") .. " (" .. (v.type or "") .. ") = " .. (v.value or ""))
    end
end

-- Get a single license variable
local lic_var_resp = client:post("/client/license-variable", { key = "max_seats" })
print("max_seats = " .. (lic_var_resp.data.value or ""))

Discord Avatar / Profile Picture

After authenticating, call POST /api/client/user to get the user's Discord avatar URL and Discord ID. The avatar URL points to the Discord CDN and supports both static (PNG) and animated (GIF) profile pictures.

Discord IDs are linked to users through licenses. Set a Discord ID on a license in the dashboard, and it transfers to the user when the license is activated.
# After init + login...

# Get user profile with Discord data
user_resp = requests.post(f"{BASE}/client/user", json={
    "sessionToken": session_token
})
user = user_resp.json()["data"]

avatar_url = user.get("avatarUrl")
discord_id = user.get("discordId")

if avatar_url:
    print(f"Discord ID: {discord_id}")
    print(f"Avatar URL: {avatar_url}")

    # Check if animated (GIF)
    if ".gif" in avatar_url:
        print("This is an animated avatar!")

    # Download the avatar image
    img_resp = requests.get(avatar_url)
    ext = "gif" if ".gif" in avatar_url else "png"
    with open(f"avatar.{ext}", "wb") as f:
        f.write(img_resp.content)
    print(f"Saved avatar.{ext}")
else:
    print("No Discord avatar linked to this user")
// After init + login...

// Get user profile with Discord data
const userResp = await fetch(`${BASE}/client/user`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ sessionToken })
});
const user = (await userResp.json()).data;

if (user.avatarUrl) {
    console.log(`Discord ID: ${user.discordId}`);
    console.log(`Avatar URL: ${user.avatarUrl}`);

    // Check if animated (GIF)
    if (user.avatarUrl.includes(".gif")) {
        console.log("This is an animated avatar!");
    }

    // Download the avatar image
    const imgResp = await fetch(user.avatarUrl);
    const ext = user.avatarUrl.includes(".gif") ? "gif" : "png";
    fs.writeFileSync(`avatar.${ext}`, Buffer.from(await imgResp.arrayBuffer()));
    console.log(`Saved avatar.${ext}`);
} else {
    console.log("No Discord avatar linked to this user");
}
// After init + login...

// Get user profile with Discord data
$userResp = swiftPost("$base/client/user", [
    "sessionToken" => $sessionToken
]);
$user = $userResp->data;

if (!empty($user->avatarUrl)) {
    echo "Discord ID: {$user->discordId}\n";
    echo "Avatar URL: {$user->avatarUrl}\n";

    // Check if animated (GIF)
    if (str_contains($user->avatarUrl, ".gif")) {
        echo "This is an animated avatar!\n";
    }

    // Download the avatar image
    $ext = str_contains($user->avatarUrl, ".gif") ? "gif" : "png";
    file_put_contents("avatar.$ext", file_get_contents($user->avatarUrl));
    echo "Saved avatar.$ext\n";
} else {
    echo "No Discord avatar linked to this user\n";
}
// After init + login...

// Get user profile with Discord data
var userJson = await SwiftPost($"{baseUrl}/client/user",
    new { sessionToken });
var userData = userJson.RootElement.GetProperty("data");

var avatarUrl = userData.GetProperty("avatarUrl").GetString();
var discordId = userData.GetProperty("discordId").GetString();

if (!string.IsNullOrEmpty(avatarUrl)) {
    Console.WriteLine($"Discord ID: {discordId}");
    Console.WriteLine($"Avatar URL: {avatarUrl}");

    // Check if animated (GIF)
    if (avatarUrl.Contains(".gif")) {
        Console.WriteLine("This is an animated avatar!");
    }

    // Download the avatar image
    var ext = avatarUrl.Contains(".gif") ? "gif" : "png";
    var imgBytes = await http.GetByteArrayAsync(avatarUrl);
    await File.WriteAllBytesAsync($"avatar.{ext}", imgBytes);
    Console.WriteLine($"Saved avatar.{ext}");
} else {
    Console.WriteLine("No Discord avatar linked to this user");
}
    // After init + login...

    // Get user profile with Discord data
    auto user_info = post_json(BASE + "/client/user", {
        {"sessionToken", sessionToken}
    });
    auto user_data = user_info["data"];

    std::string avatar_url = user_data.value("avatarUrl", "");
    std::string discord_id = user_data.value("discordId", "");

    if (!avatar_url.empty()) {
        std::cout << "Discord ID: " << discord_id << std::endl;
        std::cout << "Avatar URL: " << avatar_url << std::endl;

        // Check if animated (GIF)
        if (avatar_url.find(".gif") != std::string::npos) {
            std::cout << "This is an animated avatar!" << std::endl;
        }

        // Download the avatar image
        CURL* img_curl = curl_easy_init();
        std::string ext = (avatar_url.find(".gif") != std::string::npos) ? "gif" : "png";
        std::string img_data;
        curl_easy_setopt(img_curl, CURLOPT_URL, avatar_url.c_str());
        curl_easy_setopt(img_curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(img_curl, CURLOPT_WRITEDATA, &img_data);
        curl_easy_perform(img_curl);
        curl_easy_cleanup(img_curl);

        std::ofstream("avatar." + ext, std::ios::binary)
            .write(img_data.data(), img_data.size());
        std::cout << "Saved avatar." << ext << std::endl;
    } else {
        std::cout << "No Discord avatar linked to this user" << std::endl;
    }
    // After init + login...

    // Get user profile with Discord data
    userResp, err := client.PostJSON("/client/user", map[string]any{})
    if err != nil {
        log.Fatalf("Failed to get user: %v", err)
    }
    userData := userResp["data"].(map[string]any)
    avatarURL, _ := userData["avatarUrl"].(string)
    discordID, _ := userData["discordId"].(string)

    if avatarURL != "" {
        fmt.Printf("Discord ID: %s\n", discordID)
        fmt.Printf("Avatar URL: %s\n", avatarURL)

        // Check if animated (GIF)
        if strings.Contains(avatarURL, ".gif") {
            fmt.Println("This is an animated avatar!")
        }

        // Download the avatar image
        imgResp, err := http.Get(avatarURL)
        if err == nil {
            defer imgResp.Body.Close()
            ext := "png"
            if strings.Contains(avatarURL, ".gif") {
                ext = "gif"
            }
            imgData, _ := io.ReadAll(imgResp.Body)
            os.WriteFile("avatar."+ext, imgData, 0644)
            fmt.Printf("Saved avatar.%s\n", ext)
        }
    } else {
        fmt.Println("No Discord avatar linked to this user")
    }
    // After init + login...

    // Get user profile with Discord data
    let user_resp = client.post_json("/client/user", &serde_json::json!({}))
        .expect("Failed to get user");
    let avatar_url = user_resp["data"]["avatarUrl"].as_str().unwrap_or("");
    let discord_id = user_resp["data"]["discordId"].as_str().unwrap_or("");

    if !avatar_url.is_empty() {
        println!("Discord ID: {}", discord_id);
        println!("Avatar URL: {}", avatar_url);

        // Check if animated (GIF)
        if avatar_url.contains(".gif") {
            println!("This is an animated avatar!");
        }

        // Download the avatar image
        let img_bytes = reqwest::blocking::get(avatar_url)
            .expect("Failed to download avatar")
            .bytes()
            .expect("Failed to read avatar bytes");
        let ext = if avatar_url.contains(".gif") { "gif" } else { "png" };
        std::fs::write(format!("avatar.{}", ext), &img_bytes)
            .expect("Failed to save avatar");
        println!("Saved avatar.{}", ext);
    } else {
        println!("No Discord avatar linked to this user");
    }
        // After init + login...

        // Get user profile with Discord data
        var userResp = client.post("/client/user", Map.of());
        var userData = (Map<?, ?>) userResp.get("data");
        var avatarUrl = (String) userData.getOrDefault("avatarUrl", "");
        var discordId = (String) userData.getOrDefault("discordId", "");

        if (avatarUrl != null && !avatarUrl.isEmpty()) {
            System.out.printf("Discord ID: %s%n", discordId);
            System.out.printf("Avatar URL: %s%n", avatarUrl);

            // Check if animated (GIF)
            if (avatarUrl.contains(".gif")) {
                System.out.println("This is an animated avatar!");
            }

            // Download the avatar image
            var ext = avatarUrl.contains(".gif") ? "gif" : "png";
            try (var in = new java.net.URL(avatarUrl).openStream()) {
                java.nio.file.Files.copy(in,
                    java.nio.file.Path.of("avatar." + ext),
                    java.nio.file.StandardCopyOption.REPLACE_EXISTING);
            }
            System.out.printf("Saved avatar.%s%n", ext);
        } else {
            System.out.println("No Discord avatar linked to this user");
        }
    // After init + login...

    // Get user profile with Discord data
    val userResp = client.post("/client/user", emptyMap())
    val userData = userResp["data"] as? Map<*, *>
    val avatarUrl = userData?.get("avatarUrl") as? String ?: ""
    val discordId = userData?.get("discordId") as? String ?: ""

    if (avatarUrl.isNotEmpty()) {
        println("Discord ID: $discordId")
        println("Avatar URL: $avatarUrl")

        // Check if animated (GIF)
        if (".gif" in avatarUrl) {
            println("This is an animated avatar!")
        }

        // Download the avatar image
        val ext = if (".gif" in avatarUrl) "gif" else "png"
        java.net.URL(avatarUrl).openStream().use { input ->
            java.io.File("avatar.$ext").outputStream().use { output ->
                input.copyTo(output)
            }
        }
        println("Saved avatar.$ext")
    } else {
        println("No Discord avatar linked to this user")
    }
# After init + login...

# Get user profile with Discord data
require "net/http"
require "uri"

user_resp = client.post("/client/user", {})
user_data = user_resp["data"]
avatar_url = user_data["avatarUrl"]
discord_id = user_data["discordId"]

if avatar_url && !avatar_url.empty?
  puts "Discord ID: #{discord_id}"
  puts "Avatar URL: #{avatar_url}"

  # Check if animated (GIF)
  puts "This is an animated avatar!" if avatar_url.include?(".gif")

  # Download the avatar image
  ext = avatar_url.include?(".gif") ? "gif" : "png"
  uri = URI.parse(avatar_url)
  img_data = Net::HTTP.get(uri)
  File.binwrite("avatar.#{ext}", img_data)
  puts "Saved avatar.#{ext}"
else
  puts "No Discord avatar linked to this user"
end
// After init + login...

// Get user profile with Discord data
let userResp = try client.post(path: "/client/user", body: [:])
if let userData = userResp["data"] as? [String: Any] {
    let avatarUrl = userData["avatarUrl"] as? String ?? ""
    let discordId = userData["discordId"] as? String ?? ""

    if !avatarUrl.isEmpty {
        print("Discord ID: \(discordId)")
        print("Avatar URL: \(avatarUrl)")

        // Check if animated (GIF)
        if avatarUrl.contains(".gif") {
            print("This is an animated avatar!")
        }

        // Download the avatar image
        let ext = avatarUrl.contains(".gif") ? "gif" : "png"
        if let url = URL(string: avatarUrl) {
            let imgData = try Data(contentsOf: url)
            try imgData.write(to: URL(fileURLWithPath: "avatar.\(ext)"))
            print("Saved avatar.\(ext)")
        }
    } else {
        print("No Discord avatar linked to this user")
    }
}
-- After init + login...

-- Get user profile with Discord data
local user_resp = client:post("/client/user", {})
local user_data = user_resp.data
local avatar_url = user_data.avatarUrl or ""
local discord_id = user_data.discordId or ""

if avatar_url ~= "" then
    print("Discord ID: " .. discord_id)
    print("Avatar URL: " .. avatar_url)

    -- Check if animated (GIF)
    if avatar_url:find("%.gif") then
        print("This is an animated avatar!")
    end

    -- Download the avatar image
    local http = require("socket.http")
    local ext = avatar_url:find("%.gif") and "gif" or "png"
    local img_data = http.request(avatar_url)
    local f = io.open("avatar." .. ext, "wb")
    f:write(img_data)
    f:close()
    print("Saved avatar." .. ext)
else
    print("No Discord avatar linked to this user")
end

Full Example

Complete working example: init, login, heartbeat, download file, and clean up.

import requests
import threading
import time
import sys

BASE = "https://swiftauth.net/api"
APP_SECRET = "your-app-secret"

def get_nonce(token):
    return requests.post(f"{BASE}/client/nonce",
        json={"sessionToken": token}).json()["data"]["nonce"]

def main():
    # Init
    init = requests.post(f"{BASE}/client/init", json={
        "secret": APP_SECRET,
        "version": "1.0.0",
        "hwid": "UNIQUE-HARDWARE-ID"
    }).json()
    if not init["success"]:
        print(f"Init failed: {init['error']['message']}")
        sys.exit(1)

    token = init["data"]["sessionToken"]
    print(f"[+] Connected to {init['data']['appName']}")

    # Login
    nonce = get_nonce(token)
    login = requests.post(f"{BASE}/client/login",
        headers={"X-Nonce": nonce},
        json={
            "sessionToken": token,
            "username": "myuser",
            "password": "mypassword",
            "hwid": "UNIQUE-HARDWARE-ID"
        }
    ).json()
    if not login["success"]:
        print(f"Login failed: {login['error']['message']}")
        sys.exit(1)

    print(f"[+] Logged in as {login['data']['username']} (level {login['data']['level']})")

    # Start heartbeat
    def heartbeat():
        while True:
            try:
                n = get_nonce(token)
                r = requests.post(f"{BASE}/client/heartbeat",
                    headers={"X-Nonce": n},
                    json={"sessionToken": token}).json()
                if not r.get("success"):
                    print("[-] Session expired")
                    break
            except Exception:
                pass
            time.sleep(30)

    threading.Thread(target=heartbeat, daemon=True).start()

    # Download a file
    file_resp = requests.post(f"{BASE}/client/file", json={
        "sessionToken": token,
        "name": "loader.dll"
    })
    if file_resp.status_code == 200:
        with open("loader.dll", "wb") as f:
            f.write(file_resp.content)
        print(f"[+] Downloaded loader.dll ({len(file_resp.content)} bytes)")

    # Get variables
    vars_resp = requests.post(f"{BASE}/client/variables",
        json={"sessionToken": token}).json()
    if vars_resp["success"]:
        for v in vars_resp["data"]["variables"]:
            print(f"    {v['name']} = {v['value']}")

    # Your application logic here...
    print("[+] Application running. Press Ctrl+C to exit.")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        # End session on exit
        requests.post(f"{BASE}/client/end",
            json={"sessionToken": token})
        print("[+] Session ended. Goodbye!")

if __name__ == "__main__":
    main()
const BASE = "https://swiftauth.net/api";
const APP_SECRET = "your-app-secret";
import fs from "fs";

async function getNonce(token) {
    const r = await fetch(`${BASE}/client/nonce`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ sessionToken: token })
    });
    return (await r.json()).data.nonce;
}

async function post(url, body, nonce) {
    const headers = { "Content-Type": "application/json" };
    if (nonce) headers["X-Nonce"] = nonce;
    const r = await fetch(url, {
        method: "POST", headers,
        body: JSON.stringify(body)
    });
    return r;
}

async function main() {
    // Init
    const init = await (await post(`${BASE}/client/init`, {
        secret: APP_SECRET, version: "1.0.0", hwid: "UNIQUE-HARDWARE-ID"
    })).json();
    if (!init.success) { console.error("Init failed:", init.error.message); process.exit(1); }

    const token = init.data.sessionToken;
    console.log(`[+] Connected to ${init.data.appName}`);

    // Login
    let nonce = await getNonce(token);
    const login = await (await post(`${BASE}/client/login`, {
        sessionToken: token,
        username: "myuser",
        password: "mypassword",
        hwid: "UNIQUE-HARDWARE-ID"
    }, nonce)).json();
    if (!login.success) { console.error("Login failed:", login.error.message); process.exit(1); }

    console.log(`[+] Logged in as ${login.data.username} (level ${login.data.level})`);

    // Start heartbeat
    const hbInterval = setInterval(async () => {
        try {
            const n = await getNonce(token);
            const hb = await (await post(`${BASE}/client/heartbeat`,
                { sessionToken: token }, n)).json();
            if (!hb.success) { console.error("[-] Session expired"); clearInterval(hbInterval); }
        } catch {}
    }, 30000);

    // Download a file
    const fileResp = await post(`${BASE}/client/file`, { sessionToken: token, name: "loader.dll" });
    if (fileResp.ok) {
        fs.writeFileSync("loader.dll", Buffer.from(await fileResp.arrayBuffer()));
        console.log("[+] Downloaded loader.dll");
    }

    // Get variables
    const vars = await (await post(`${BASE}/client/variables`, { sessionToken: token })).json();
    if (vars.success) vars.data.variables.forEach(v => console.log(`    ${v.name} = ${v.value}`));

    // Cleanup on exit
    process.on("SIGINT", async () => {
        clearInterval(hbInterval);
        await post(`${BASE}/client/end`, { sessionToken: token });
        console.log("[+] Session ended. Goodbye!");
        process.exit(0);
    });

    console.log("[+] Application running. Press Ctrl+C to exit.");
}

main();
<?php
$base = "https://swiftauth.net/api";
$appSecret = "your-app-secret";

function swiftPost($url, $data, $nonce = null) {
    $headers = "Content-Type: application/json\r\n";
    if ($nonce) $headers .= "X-Nonce: $nonce\r\n";
    $ctx = stream_context_create(["http" => [
        "method" => "POST",
        "header" => $headers,
        "content" => json_encode($data)
    ]]);
    return json_decode(file_get_contents($url, false, $ctx));
}

function getNonce($base, $token) {
    return swiftPost("$base/client/nonce", ["sessionToken" => $token])->data->nonce;
}

// Init
$init = swiftPost("$base/client/init", [
    "secret" => $appSecret, "version" => "1.0.0", "hwid" => "UNIQUE-HARDWARE-ID"
]);
if (!$init->success) { echo "Init failed: {$init->error->message}\n"; exit(1); }
$token = $init->data->sessionToken;
echo "[+] Connected to {$init->data->appName}\n";

// Login
$nonce = getNonce($base, $token);
$login = swiftPost("$base/client/login", [
    "sessionToken" => $token,
    "username" => "myuser",
    "password" => "mypassword",
    "hwid" => "UNIQUE-HARDWARE-ID"
], $nonce);
if (!$login->success) { echo "Login failed: {$login->error->message}\n"; exit(1); }
echo "[+] Logged in as {$login->data->username} (level {$login->data->level})\n";

// Download a file
$ch = curl_init("$base/client/file");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS => json_encode(["sessionToken" => $token, "name" => "loader.dll"]),
    CURLOPT_RETURNTRANSFER => true
]);
$fileData = curl_exec($ch);
curl_close($ch);
file_put_contents("loader.dll", $fileData);
echo "[+] Downloaded loader.dll (" . strlen($fileData) . " bytes)\n";

// Get variables
$vars = swiftPost("$base/client/variables", ["sessionToken" => $token]);
if ($vars->success) {
    foreach ($vars->data->variables as $v) {
        echo "    {$v->name} = {$v->value}\n";
    }
}

// Heartbeat loop (for CLI scripts)
echo "[+] Running with heartbeat. Press Ctrl+C to exit.\n";
while (true) {
    $nonce = getNonce($base, $token);
    $hb = swiftPost("$base/client/heartbeat", ["sessionToken" => $token], $nonce);
    if (!($hb->success ?? false)) { echo "[-] Session expired\n"; break; }
    sleep(30);
}

// End session
swiftPost("$base/client/end", ["sessionToken" => $token]);
echo "[+] Session ended. Goodbye!\n";
using System.Net.Http;
using System.Text;
using System.Text.Json;

var baseUrl = "https://swiftauth.net/api";
var appSecret = "your-app-secret";
var http = new HttpClient();

async Task<JsonDocument> SwiftPost(string url, object body, string? nonce = null) {
    var req = new HttpRequestMessage(HttpMethod.Post, url);
    req.Content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
    if (nonce != null) req.Headers.Add("X-Nonce", nonce);
    var resp = await http.SendAsync(req);
    return JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
}

async Task<string> GetNonce(string token) {
    var r = await SwiftPost($"{baseUrl}/client/nonce", new { sessionToken = token });
    return r.RootElement.GetProperty("data").GetProperty("nonce").GetString()!;
}

// Init
var init = await SwiftPost($"{baseUrl}/client/init", new {
    secret = appSecret, version = "1.0.0", hwid = "UNIQUE-HARDWARE-ID"
});
var initData = init.RootElement.GetProperty("data");
var sessionToken = initData.GetProperty("sessionToken").GetString()!;
Console.WriteLine($"[+] Connected to {initData.GetProperty("appName")}");

// Login
var nonce = await GetNonce(sessionToken);
var login = await SwiftPost($"{baseUrl}/client/login", new {
    sessionToken, username = "myuser", password = "mypassword", hwid = "UNIQUE-HARDWARE-ID"
}, nonce);
var user = login.RootElement.GetProperty("data");
Console.WriteLine($"[+] Logged in as {user.GetProperty("username")} (level {user.GetProperty("level")})");

// Start heartbeat
var cts = new CancellationTokenSource();
_ = Task.Run(async () => {
    while (!cts.Token.IsCancellationRequested) {
        try {
            var n = await GetNonce(sessionToken);
            await SwiftPost($"{baseUrl}/client/heartbeat", new { sessionToken }, n);
        } catch {}
        await Task.Delay(30000, cts.Token);
    }
});

// Download a file
var fileReq = new HttpRequestMessage(HttpMethod.Post, $"{baseUrl}/client/file");
fileReq.Content = new StringContent(
    JsonSerializer.Serialize(new { sessionToken, name = "loader.dll" }),
    Encoding.UTF8, "application/json");
var fileResp = await http.SendAsync(fileReq);
if (fileResp.IsSuccessStatusCode) {
    var bytes = await fileResp.Content.ReadAsByteArrayAsync();
    await File.WriteAllBytesAsync("loader.dll", bytes);
    Console.WriteLine($"[+] Downloaded loader.dll ({bytes.Length} bytes)");
}

// Get variables
var vars = await SwiftPost($"{baseUrl}/client/variables", new { sessionToken });
foreach (var v in vars.RootElement.GetProperty("data").GetProperty("variables").EnumerateArray()) {
    Console.WriteLine($"    {v.GetProperty("name")} = {v.GetProperty("value")}");
}

// Cleanup on exit
Console.CancelKeyPress += async (s, e) => {
    e.Cancel = true;
    cts.Cancel();
    await SwiftPost($"{baseUrl}/client/end", new { sessionToken });
    Console.WriteLine("[+] Session ended. Goodbye!");
    Environment.Exit(0);
};

Console.WriteLine("[+] Application running. Press Ctrl+C to exit.");
await Task.Delay(-1, cts.Token);
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include <iostream>
#include <fstream>
#include <thread>
#include <chrono>
#include <atomic>
#include <string>

using json = nlohmann::json;

const std::string BASE = "https://swiftauth.net/api";
const std::string APP_SECRET = "your-app-secret";

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* out) {
    out->append((char*)contents, size * nmemb);
    return size * nmemb;
}

json post_json(const std::string& url, const json& body, const std::string& nonce = "") {
    CURL* curl = curl_easy_init();
    std::string response;
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    if (!nonce.empty()) headers = curl_slist_append(headers, ("X-Nonce: " + nonce).c_str());
    std::string payload = body.dump();
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    curl_easy_perform(curl);
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return json::parse(response);
}

int main() {
    curl_global_init(CURL_GLOBAL_DEFAULT);

    // Init
    auto init = post_json(BASE + "/client/init", {
        {"secret", APP_SECRET}, {"version", "1.0.0"}, {"hwid", "UNIQUE-HARDWARE-ID"}
    });
    if (!init["success"].get<bool>()) {
        std::cerr << "Init failed: " << init["error"]["message"] << std::endl;
        return 1;
    }
    std::string token = init["data"]["sessionToken"];
    std::cout << "[+] Connected to " << init["data"]["appName"] << std::endl;

    // Helper: get nonce
    auto get_nonce = [&]() {
        return post_json(BASE + "/client/nonce",
            {{"sessionToken", token}})["data"]["nonce"].get<std::string>();
    };

    // Login
    auto login = post_json(BASE + "/client/login", {
        {"sessionToken", token}, {"username", "myuser"},
        {"password", "mypassword"}, {"hwid", "UNIQUE-HARDWARE-ID"}
    }, get_nonce());
    if (!login["success"].get<bool>()) {
        std::cerr << "Login failed: " << login["error"]["message"] << std::endl;
        return 1;
    }
    std::cout << "[+] Logged in as " << login["data"]["username"]
              << " (level " << login["data"]["level"] << ")" << std::endl;

    // Heartbeat thread
    std::atomic<bool> running{true};
    std::thread hb_thread([&]() {
        while (running) {
            try {
                auto hb = post_json(BASE + "/client/heartbeat",
                    {{"sessionToken", token}}, get_nonce());
                if (!hb.value("success", false)) {
                    std::cerr << "[-] Session expired" << std::endl;
                    break;
                }
            } catch (...) {}
            std::this_thread::sleep_for(std::chrono::seconds(30));
        }
    });
    hb_thread.detach();

    // Download a file
    CURL* dl = curl_easy_init();
    std::string file_data;
    json dl_body = {{"sessionToken", token}, {"name", "loader.dll"}};
    std::string dl_payload = dl_body.dump();
    struct curl_slist* dl_h = nullptr;
    dl_h = curl_slist_append(dl_h, "Content-Type: application/json");
    curl_easy_setopt(dl, CURLOPT_URL, (BASE + "/client/file").c_str());
    curl_easy_setopt(dl, CURLOPT_POSTFIELDS, dl_payload.c_str());
    curl_easy_setopt(dl, CURLOPT_HTTPHEADER, dl_h);
    curl_easy_setopt(dl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(dl, CURLOPT_WRITEDATA, &file_data);
    curl_easy_perform(dl);
    curl_slist_free_all(dl_h);
    curl_easy_cleanup(dl);
    std::ofstream("loader.dll", std::ios::binary).write(file_data.data(), file_data.size());
    std::cout << "[+] Downloaded loader.dll (" << file_data.size() << " bytes)" << std::endl;

    // Get variables
    auto vars = post_json(BASE + "/client/variables", {{"sessionToken", token}});
    if (vars["success"].get<bool>()) {
        for (auto& v : vars["data"]["variables"]) {
            std::cout << "    " << v["name"].get<std::string>()
                      << " = " << v["value"].get<std::string>() << std::endl;
        }
    }

    // Your application logic here...
    std::cout << "[+] Application running. Press Enter to exit." << std::endl;
    std::cin.get();

    // Cleanup
    running = false;
    post_json(BASE + "/client/end", {{"sessionToken", token}});
    std::cout << "[+] Session ended. Goodbye!" << std::endl;

    curl_global_cleanup();
    return 0;
}
package main

import (
    "fmt"
    "log"
    "os"
    "os/signal"
    "time"

    swiftauth "github.com/swiftauth/swiftauth-go"
)

func main() {
    client := swiftauth.NewClient(
        "https://api.swiftauth.net",
        "your-app-secret",
        "1.0.0",
        "UNIQUE-HARDWARE-ID",
    )

    // Init
    _, err := client.Init()
    if err != nil {
        log.Fatalf("Init failed: %v", err)
    }
    fmt.Printf("[+] Connected to %s v%s\n", client.App.Name, client.App.Version)

    // Login
    _, err = client.Login("myuser", "mypassword", "", "")
    if err != nil {
        log.Fatalf("Login failed: %v", err)
    }
    fmt.Printf("[+] Logged in as %s (level %d)\n", client.User.Username, client.User.Level)

    // Start heartbeat in background
    go func() {
        for {
            if _, err := client.Heartbeat(); err != nil {
                fmt.Println("[-] Session expired")
                return
            }
            time.Sleep(30 * time.Second)
        }
    }()

    // Download a file
    fileData, err := client.DownloadFile("loader.dll")
    if err == nil {
        os.WriteFile("loader.dll", fileData, 0644)
        fmt.Printf("[+] Downloaded loader.dll (%d bytes)\n", len(fileData))
    }

    // Get variables
    vars, err := client.GetAllVariables()
    if err == nil {
        for _, v := range vars {
            fmt.Printf("    %s = %s\n", v.Key, v.Value)
        }
    }

    // Wait for interrupt, then clean up
    fmt.Println("[+] Application running. Press Ctrl+C to exit.")
    sig := make(chan os.Signal, 1)
    signal.Notify(sig, os.Interrupt)
    <-sig

    client.EndSession()
    fmt.Println("[+] Session ended. Goodbye!")
}
use swiftauth::SwiftAuthClient;
use std::thread;
use std::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

fn main() {
    let mut client = SwiftAuthClient::new(
        "https://api.swiftauth.net",
        "your-app-secret",
        "1.0.0",
        Some("UNIQUE-HARDWARE-ID"),
    );

    // Init
    client.init().expect("Init failed");
    let app = client.app.as_ref().unwrap();
    println!("[+] Connected to {} v{}", app.name, app.version);

    // Login
    client.login("myuser", "mypassword", None, "")
        .expect("Login failed");
    let user = client.user.as_ref().unwrap();
    println!("[+] Logged in as {} (level {})", user.username, user.level);

    // Note: For heartbeat in a background thread, you would need
    // to share the client across threads with Arc<Mutex<...>>.
    // Sending a single heartbeat here for demonstration:
    client.heartbeat().expect("Heartbeat failed");

    // Download a file
    match client.download_file("loader.dll") {
        Ok(data) => {
            std::fs::write("loader.dll", &data).expect("Write failed");
            println!("[+] Downloaded loader.dll ({} bytes)", data.len());
        }
        Err(e) => eprintln!("Download error: {}", e),
    }

    // Get variables
    match client.get_all_variables() {
        Ok(vars) => {
            for v in &vars {
                println!("    {} = {}", v.key, v.value);
            }
        }
        Err(e) => eprintln!("Variables error: {}", e),
    }

    // Your application logic here...
    println!("[+] Application running. Press Enter to exit.");
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).ok();

    // Cleanup
    client.end_session().ok();
    println!("[+] Session ended. Goodbye!");
}
import net.swiftauth.SwiftAuthClient;
import net.swiftauth.SwiftAuthException;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.List;

public class FullExample {
    public static void main(String[] args) {
        var client = new SwiftAuthClient(
            "https://api.swiftauth.net",
            "your-app-secret",
            "1.0.0",
            "UNIQUE-HARDWARE-ID"
        );

        try {
            // Init
            client.init();
            System.out.printf("[+] Connected to %s v%s%n",
                client.getApp().name(), client.getApp().version());

            // Login
            client.login("myuser", "mypassword");
            System.out.printf("[+] Logged in as %s (level %d)%n",
                client.getUser().username(), client.getUser().level());

            // Start heartbeat in background
            Thread hbThread = new Thread(() -> {
                while (true) {
                    try {
                        client.heartbeat();
                    } catch (SwiftAuthException e) {
                        System.err.println("[-] Session expired: " + e.getMessage());
                        break;
                    }
                    try { Thread.sleep(30000); } catch (InterruptedException ignored) { break; }
                }
            });
            hbThread.setDaemon(true);
            hbThread.start();

            // Download a file
            byte[] fileData = client.downloadFile("loader.dll");
            Files.write(Path.of("loader.dll"), fileData);
            System.out.printf("[+] Downloaded loader.dll (%d bytes)%n", fileData.length);

            // Get variables
            Map<String, Object> varsData = client.getAllVariables();
            Object list = varsData.get("_list");
            if (list instanceof List<?> varList) {
                for (Object item : varList) {
                    if (item instanceof Map<?,?> v) {
                        System.out.printf("    %s = %s%n", v.get("key"), v.get("value"));
                    }
                }
            }

            // Your application logic here...
            System.out.println("[+] Application running. Press Enter to exit.");
            System.in.read();

            // Cleanup
            client.endSession();
            System.out.println("[+] Session ended. Goodbye!");

        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            System.exit(1);
        }
    }
}
import net.swiftauth.SwiftAuthClient
import net.swiftauth.SwiftAuthException
import kotlin.concurrent.thread

fun main() {
    val client = SwiftAuthClient(
        baseUrl = "https://api.swiftauth.net",
        secret = "your-app-secret",
        version = "1.0.0",
        hwid = "UNIQUE-HARDWARE-ID"
    )

    try {
        // Init
        client.init()
        println("[+] Connected to ${client.app?.name} v${client.app?.version}")

        // Login
        client.login("myuser", "mypassword")
        println("[+] Logged in as ${client.user?.username} (level ${client.user?.level})")

        // Start heartbeat in background
        thread(isDaemon = true) {
            while (true) {
                try {
                    client.heartbeat()
                } catch (e: SwiftAuthException) {
                    println("[-] Session expired: ${e.message}")
                    break
                }
                Thread.sleep(30000)
            }
        }

        // Download a file
        val fileData = client.downloadFile("loader.dll")
        java.io.File("loader.dll").writeBytes(fileData)
        println("[+] Downloaded loader.dll (${fileData.size} bytes)")

        // Get variables
        val vars = client.getAllVariables()
        for (v in vars) {
            println("    ${v.key} = ${v.value}")
        }

        // Your application logic here...
        println("[+] Application running. Press Enter to exit.")
        readlnOrNull()

        // Cleanup
        client.endSession()
        println("[+] Session ended. Goodbye!")

    } catch (e: SwiftAuthException) {
        System.err.println("Error: ${e.message}")
        kotlin.system.exitProcess(1)
    }
}
require "swiftauth"

client = SwiftAuth::Client.new(
  base_url: "https://api.swiftauth.net",
  app_secret: "your-app-secret",
  app_version: "1.0.0",
  hwid: "UNIQUE-HARDWARE-ID"
)

begin
  # Init
  client.init
  puts "[+] Connected to #{client.app.name} v#{client.app.version}"

  # Login
  client.login("myuser", "mypassword")
  puts "[+] Logged in as #{client.user.username} (level #{client.user.level})"

  # Start heartbeat in background
  heartbeat_thread = Thread.new do
    loop do
      begin
        client.heartbeat
      rescue SwiftAuth::Error => e
        puts "[-] Session expired: #{e.message}"
        break
      end
      sleep 30
    end
  end

  # Download a file
  file_data = client.download_file("loader.dll")
  File.binwrite("loader.dll", file_data)
  puts "[+] Downloaded loader.dll (#{file_data.bytesize} bytes)"

  # Get variables
  vars = client.get_all_variables
  vars.each { |v| puts "    #{v.key} = #{v.value}" }

  # Your application logic here...
  puts "[+] Application running. Press Ctrl+C to exit."
  sleep

rescue Interrupt
  # Cleanup
  client.end_session
  puts "[+] Session ended. Goodbye!"
rescue SwiftAuth::Error => e
  puts "Error: #{e.message}"
  exit 1
end
import Foundation

let client = SwiftAuthClient(
    baseURL: "https://api.swiftauth.net",
    appSecret: "your-app-secret",
    appVersion: "1.0.0",
    hwid: "UNIQUE-HARDWARE-ID"
)

do {
    // Init
    try client.initialize()
    print("[+] Connected to \(client.app!.name) v\(client.app!.version)")

    // Login
    try client.login(username: "myuser", password: "mypassword")
    print("[+] Logged in as \(client.user!.username) (level \(client.user!.level))")

    // Start heartbeat in background
    let heartbeatQueue = DispatchQueue(label: "heartbeat", qos: .background)
    heartbeatQueue.async {
        while true {
            do {
                try client.heartbeat()
            } catch {
                print("[-] Session expired: \(error)")
                break
            }
            Thread.sleep(forTimeInterval: 30)
        }
    }

    // Download a file
    let fileData = try client.downloadFile(name: "loader.dll")
    try fileData.write(to: URL(fileURLWithPath: "loader.dll"))
    print("[+] Downloaded loader.dll (\(fileData.count) bytes)")

    // Get variables
    let vars = try client.getAllVariables()
    for v in vars {
        print("    \(v.key) = \(v.value)")
    }

    // Your application logic here...
    print("[+] Application running. Press Enter to exit.")
    _ = readLine()

    // Cleanup
    try client.endSession()
    print("[+] Session ended. Goodbye!")

} catch let e as SwiftAuthError {
    print("Error: [\(e.code)] \(e.message)")
    exit(1)
} catch {
    print("Error: \(error)")
    exit(1)
}
local SwiftAuth = require("swiftauth")

local client = SwiftAuth.new(
    "https://api.swiftauth.net",
    "your-app-secret",
    "1.0.0",
    "UNIQUE-HARDWARE-ID"
)

-- Init
local ok, err = pcall(function() client:init() end)
if not ok then print("Init failed: " .. tostring(err)); os.exit(1) end
print("[+] Connected to " .. client.app.name .. " v" .. client.app.version)

-- Login
ok, err = pcall(function() client:login("myuser", "mypassword") end)
if not ok then print("Login failed: " .. tostring(err)); os.exit(1) end
print("[+] Logged in as " .. client.user.username .. " (level " .. client.user.level .. ")")

-- Heartbeat (single call; for continuous use, integrate with your event loop)
ok, err = pcall(function() client:heartbeat() end)
if not ok then print("Heartbeat failed: " .. tostring(err)) end

-- Download a file
ok, err = pcall(function()
    local file_data = client:download_file("loader.dll")
    local f = io.open("loader.dll", "wb")
    f:write(file_data)
    f:close()
    print("[+] Downloaded loader.dll (" .. #file_data .. " bytes)")
end)
if not ok then print("Download error: " .. tostring(err)) end

-- Get variables
ok, err = pcall(function()
    local vars = client:get_all_variables()
    for _, v in ipairs(vars) do
        print("    " .. v.key .. " = " .. v.value)
    end
end)
if not ok then print("Variables error: " .. tostring(err)) end

-- Your application logic here...
print("[+] Application running. Press Enter to exit.")
io.read("*l")

-- Cleanup
pcall(function() client:end_session() end)
print("[+] Session ended. Goodbye!")