Floating Licenses

Licensing Features

Floating / Concurrent Licenses

Floating licenses (also called concurrent licenses) let multiple users share a pool of seats. Instead of permanently consuming an activation slot, a user checks out a seat when the app starts and returns it when they close it.

Example: a company has 50 employees but only 10 ever use the software at the same time. You sell them a license with 10 concurrent seats — far cheaper than 50 individual activations.

Available on Starter (up to 5 concurrent seats per license) and unlimited on Professional and Enterprise. Not available on Free.
Floating license in admin panel

Creating a floating license — toggle the Floating mode and set the maximum concurrent sessions.

How floating sessions work

ActionSDK callWhat happens
App startsPOST /api/v1/float/checkoutA session is created. If max concurrent seats are in use, returns an error — app should show "all seats in use".
Every 4–5 minPOST /api/v1/float/heartbeat (body: {"sessionToken":"..."})Extends the session expiry by 15 minutes. Without heartbeat, session expires automatically.
App closesPOST /api/v1/float/checkin (body: {"sessionToken":"..."})Releases the seat immediately. Other users can check it out instantly.
Sessions expire after 15 minutes without a heartbeat. Always implement the heartbeat in your SDK — typically in a background thread or timer that fires every 4 minutes. On unexpected app crash, the stale session will auto-expire within 15 minutes.

Creating a floating license

  1. Go to Licenses → Create
  2. Toggle "Floating / Concurrent License"
  3. Set Max Concurrent Sessions (blank = unlimited)
  4. Generate and distribute the key as usual

SDK example (checkout + heartbeat)

C# (.NET SDK)
var session = await client.CheckoutAsync("PERMIT-XXXX-XXXX-XXXX-XXXX");
if (!session.Success)
{
    ShowMessage($"All seats in use: {session.Message}");
    return;
}

// Keep alive every 4 minutes
using var hb = new Timer(async _ =>
    await client.HeartbeatAsync(session.SessionToken!),
    null, TimeSpan.FromMinutes(4), TimeSpan.FromMinutes(4));

// Release on exit
AppDomain.CurrentDomain.ProcessExit += async (_, _) =>
    await client.CheckinAsync(session.SessionToken!);
Python (Python SDK)
session = client.checkout("PERMIT-XXXX-XXXX-XXXX-XXXX")
if not session.success:
    print(f"All seats in use: {session.message}")
    raise SystemExit(1)

# Heartbeat in background thread (see full Python SDK docs)
# Release on exit:
import atexit
atexit.register(client.checkin, session.session_token)

Viewing active sessions

You can see all active sessions for a license via the API: POST /api/v1/float/sessions (body: {"licenseKey":"..."}, requires an authenticated JWT — a license key is a sensitive credential). Sessions that have missed their heartbeat window are automatically cleaned up on the next query.