Integration Guide.

Add machine-bound licensing to your software. Follow each step in order. Copy the code exactly.

Install the SDK
Add the Archergate license library to your project. Pick your language.
Rust
C / C++
Python
cargo add archergate-license
# Download the static library for your platform: github.com/lailaarcher/archergate/releases # Place archergate_license.h and .lib/.a in your project
pip install archergate
Create a license client
Initialize with your API key and plugin ID. You get both from your dashboard after signing up.
Rust
C / C++
Python
use archergate_license::LicenseClient; let client = LicenseClient::new( "your-api-key", // from dashboard → API Keys "com.you.yourapp", // your plugin ID );
#include "archergate_license.h" AgLicenseClient* client = ag_license_new( "your-api-key", // from dashboard → API Keys "com.you.yourapp" // your plugin ID );
from archergate import LicenseClient client = LicenseClient( api_key="your-api-key", # from dashboard → API Keys plugin_id="com.you.yourapp", # your plugin ID )
Validate on launch
Call validate() when your app starts. Pass the license key the user entered. This checks the key against the server and binds it to this machine.
Rust
C / C++
Python
let result = client.validate("XXXX-XXXX-XXXX-XXXX"); match result { Ok(receipt) => { // License is valid. App runs normally. // Receipt is cached locally for 30-day offline use. } Err(e) => { // License invalid or expired. // Show "enter your license key" dialog. eprintln!("License error: {}", e); } }
int valid = ag_license_validate(client, "XXXX-XXXX-XXXX-XXXX"); if (valid) { // License is valid. App runs normally. // Receipt is cached locally for 30-day offline use. } else { // License invalid or expired. // Show "enter your license key" dialog. }
result = client.validate("XXXX-XXXX-XXXX-XXXX") if result.valid: # License is valid. App runs normally. # Receipt is cached locally for 30-day offline use. else: # License invalid or expired. # Show "enter your license key" dialog. print(f"License error: {result.error}")
Where exactly does this go?
Pick your framework. These show the exact file and function where you add the license check.
JUCE
Tauri
Unity
Python
Electron
// File: Source/PluginProcessor.cpp // Function: prepareToPlay() #include "archergate_license.h" void YourPluginProcessor::prepareToPlay( double sampleRate, int samplesPerBlock) { // ── Archergate license check ── AgLicenseClient* ag = ag_license_new( "your-api-key", "com.you.yourplugin" ); // Read key from saved plugin state or show dialog juce::String key = getSavedLicenseKey(); if (!ag_license_validate(ag, key.toRawUTF8())) { // License invalid → mute output or show trial nag mLicensed = false; } else { mLicensed = true; } ag_license_free(ag); // ... rest of your prepareToPlay setup } // File: Source/PluginProcessor.h // Add to private members: bool mLicensed = false; // File: Source/PluginProcessor.cpp // In processBlock(), check before processing: if (!mLicensed) { buffer.clear(); // silence output if unlicensed return; }
Build setup: Add archergate_license.h to Source/ and the static lib to your Projucer/CMake link libraries.
// File: src-tauri/src/main.rs // Add to Cargo.toml: archergate-license = "0.1" use archergate_license::LicenseClient; fn main() { // ── Archergate license check (before Tauri starts) ── let client = LicenseClient::new( "your-api-key", "com.you.yourapp", ); // Read key from local storage or config file let key = std::fs::read_to_string("license.txt") .unwrap_or_default(); let licensed = match client.validate(&key) { Ok(_receipt) => true, Err(_) => false, }; tauri::Builder::default() .manage(LicenseState { licensed }) .run(tauri::generate_context!()) .expect("error running app"); } struct LicenseState { licensed: bool }
// File: Assets/Plugins/LicenseCheck.cs // Attach to a GameObject in your first scene using System.Runtime.InteropServices; using UnityEngine; public class LicenseCheck : MonoBehaviour { // P/Invoke to the Archergate C library [DllImport("archergate_license")] static extern System.IntPtr ag_license_new( string apiKey, string pluginId); [DllImport("archergate_license")] static extern bool ag_license_validate( System.IntPtr client, string key); [DllImport("archergate_license")] static extern void ag_license_free( System.IntPtr client); public static bool IsLicensed { get; private set; } void Awake() { var client = ag_license_new( "your-api-key", "com.you.yourasset" ); string key = PlayerPrefs.GetString("license_key", ""); IsLicensed = ag_license_validate(client, key); ag_license_free(client); if (!IsLicensed) Debug.LogWarning("Archergate: unlicensed"); } } // Place archergate_license.dll/.so/.dylib in Assets/Plugins/
# File: your_app/main.py (or __init__.py for Blender addons) # pip install archergate from archergate import LicenseClient import sys def check_license(): client = LicenseClient( api_key="your-api-key", plugin_id="com.you.youraddon", ) # Read key from config file or environment variable key = os.environ.get("ARCHERGATE_KEY", "") result = client.validate(key) if not result.valid: print(f"License error: {result.error}") sys.exit(1) return True # Call at the top of your app entry point: check_license() # For Blender addons, call in register(): def register(): check_license() # ... register your panels, operators, etc.
// File: src/main.js (Electron main process) // npm install archergate-node const { LicenseClient } = require('archergate-node'); const { app, BrowserWindow } = require('electron'); const Store = require('electron-store'); const store = new Store(); let licensed = false; app.whenReady().then(async () => { // ── Archergate license check ── const client = new LicenseClient( "your-api-key", "com.you.yourapp" ); const key = store.get('license_key', ''); const result = await client.validate(key); licensed = result.valid; if (!licensed) { // Show license entry window createLicenseWindow(); } else { createMainWindow(); } });
Where the license key comes from
You don't generate keys yourself. When a buyer purchases your product through Archergate checkout, a key is created and emailed to them automatically.
Your app just needs a text field where the user pastes their key. That string goes into validate().
Key format: XXXX-XXXX-XXXX-XXXX
Offline? It still works.
After one successful validation, the SDK saves an HMAC-signed receipt to disk. For the next 30 days, your app validates locally without hitting the server.
No internet on a tour bus, recording studio, or airplane? The receipt covers it. After 30 days, the SDK checks in once and refreshes.
Create your product on Archergate
Sign up at /developers, then go to your dashboard:
Dashboard → Products → New product Name: "Your App Name" Plugin ID: "com.you.yourapp" ← must match step 2 Price: "$29.00" Category: "Audio Plugins" ← or Desktop Apps, Dev Tools, etc. Download URL: "https://your-site.com/download" Listed: yes ← makes it appear on marketplace
Then generate an API key under Dashboard → API Keys. Paste that key into step 2.
Test the full flow
Use Stripe test mode to simulate a purchase. Archergate generates a real license key and emails it to the test buyer.
# 1. Go to your product page on the marketplace # 2. Buy with Stripe test card: 4242 4242 4242 4242 # 3. Check your email for the license key # 4. Paste it into your app # 5. validate() should return valid ✓
Ship it
Push your binary. Your app is now copy-protected. When someone buys through the marketplace or a direct link, they get a key instantly. The SDK handles the rest.
Works with
JUCE
JUCE
Unity
Unity
Unreal
Unreal
Blender
Blender
Tauri
Tauri
Electron
Electron
AutoCAD
AutoCAD
Revit
Revit
Python
Python
Rust
Rust
C/C++
C / C++
Download
Windows .lib x64 macOS .a universal Linux .a x64
Pricing
SDKfree forever
Self-hostfree forever
We host it$7/mo
Questions

Why Rust?

Memory-safe, no runtime, C-compatible FFI, under 200KB compiled. Works inside any host. Read the full guide →

What does this replace?

Custom license code, Keygen, iLok, Gumroad license API. This is a library, not a platform.

What if Archergate disappears?

MIT licensed. Fork it, vendor it, rewrite the server. Your product depends on your copy, not ours.

What data touches your servers?

Nothing if you self-host. License key, machine fingerprint, activation date. No analytics, no telemetry.

© 2026 Archergate · San Francisco, California