Skip to content
Back to Launch documentation

Download MarkdownOriginal source on GitHub

Manual integration guide (9 languages, no AI needed)

This guide is for Licentivo providers. Merchants with other existing authorization systems can select custom service in the backend under 'Authorization Selection and Customization,' integrate according to Custom Authorization API and Integration Process , and continue using their own authorization system SDK.

Currently unpublished changes adopt account identity exchange. Specific responsibilities and migration constraints are detailed in Purchase Term and Account SDK Boundaries . Launch calculates the purchase term; Licentivo SDK executes authorization.

Only install the Launch integration package for the corresponding language. The Launch package internally includes the official SDK, default adapter, and link configuration; the official authorization address is fixed at https://www.licentivo.com. The program logs in using the account registered by the purchaser in the current Launch store.

Obtain the completed initialization code

  1. Complete the association of software, sales packages, and Licentivo authorization strategies in the Launch backend, and release it in the corresponding environment.
  2. Open Program Access → Access Check and Code, and select software, language, and test/production environment.
  3. Click 'Read Product Information and Generate Access Code'. Launch automatically reads the current public address of the site, existing product mappings, and signature public key.
  4. Copy the link function on the page into your own project, and manually write the interface and business calls as described below. You can also view the automatically filled parameters and directly call the corresponding language version of Connect/connect.

No need to manually fill in the two internal product IDs, and there is no need to generate launch-config.json or product.json. The page can save the source code link function. The server private config.yaml is only for Launch service startup and cannot be released with customer software.

The site address comes from the current instance's valid public address (start configuration public_url, or valid public address in the backend website settings). It can be a domain name or an IP address with a port, but it must include a protocol; production access uses valid HTTPS. The listening address http_addr is not a customer access address. After changing the site address, product mapping, or environment, retrieve the link function from the current site again; sessions and caches from the old site cannot be used for new site authorization.

The two product numbers are existing internal correspondences: Launch software product and Licentivo authorization product. The access page automatically fills them in according to the selected software; the purchaser only enters the store account. The signature public key is read by the server using the configured Licentivo, and the management key and customer authorization credentials do not enter the source code.

The function of Connect/connect

Connect/connect is the name used in different languages for the operation “create Launch application client.” Go, C#, and some native interfaces use capitalized Connect, while Python, JavaScript, Ruby, and other languages use connect according to their own styles. The backend-generated connectLaunch(), connect_launch(), or LaunchConnection.Open() are project functions with public parameters pre-filled and internally call the corresponding language entry points.

Connection only completes initialization: it verifies the store address, product mapping, environment, and signature public key, creates a Launch client, and configures the official Licentivo SDK inside the package. It does not verify the customer identity nor directly enable paid features. The full sequence is:

Connect/connect → Login or Restore → RunFeature → Logout / Close
                                       └──────────→ ReleaseDevice (explicit device unlink only)

During app runtime, you should keep the same client object so the SDK can properly handle heartbeats and floating seats. Normal close keeps device binding; when the customer explicitly exits, calling the entrance compatible with ReleaseDevice uses the same official SDK exit flow.

Installation and initialization entry

Version 0.1.6’s installation verification for nine languages has all passed (9/9). The installation methods in the table below have all been verified. GitHub Release also provides native packages and offline files; usage instructions see download package installation instructions .

Language Install only Launch Connection functions provided by the page Directly initialize API within the package
Go go get github.com/spf86/licentivo-launch-sdk/pkg/launchclient@v0.1.6 connectLaunch() launchclient.Connect
Python 3.10+ python -m pip install licentivo-launch==0.1.6 connect_launch() Application.connect
C# / .NET 8+ dotnet add package Licentivo.Launch --version 0.1.6 LaunchConnection.Open() Application.Connect
Java 17+ Maven/Gradle:com.licentivo.launch:launch-client:0.1.6 LaunchConnection.open() Launch.connect
Node.js 20.3+ npm install @licentivo/launch@0.1.6 connectLaunch() Application.connect
Rust 1.85+ cargo add licentivo-launch@=0.1.6 connect_launch() Application::connect
Ruby 3.1+ gem install licentivo-launch --version 0.1.6 connect_launch Application.connect
C11 Download native package from GitHub Release, import via CMake connect_launch() launch_application_connect
C++17 Use the same Launch native package connectLaunch() Application::Connect

The source code and README files for each language are available at Launch SDK repository, native packages and offline files can be found at v0.1.6 Release, and public installation results are at Registry verification in nine languages. Each package's own README provides installation commands and APIs. The JavaScript package includes TypeScript declarations. Dependencies for normal languages are resolved by the package manager, such as Python's cryptography, C#'s BouncyCastle, and Ruby's base64; there’s no need to install the official SDK package.

The Go public module is named github.com/spf86/licentivo-launch-sdk, with the import path github.com/spf86/licentivo-launch-sdk/pkg/launchclient, and the application doesn’t need a local replace. The Windows native package uses amd64 GNU/MinGW, and there is also a Linux amd64 native package. The Ruby platform package and Rust/native Windows distribution include curl; building from source on other platforms requires standard C11 and curl/OpenSSL development dependencies. Toolchain details are in each package's README.

Login and Protected Operations

The following snippets use the connect function copied in the previous step. email and password come from your own login interface; do not write passwords into source code or config. export must be replaced with a feature name that actually exists in the package plan.

Go

app, err := connectLaunch()
if err != nil { return err }
defer app.Close()
if _, err := app.Login(ctx, email, password); err != nil { return err }
return app.RunFeature("export", func() error {
    return exportReport()
})

ctx uses the application lifecycle context, and you shouldn’t cancel heartbeats immediately after a login request. Network operations run on a background worker thread. Use Restore(ctx) for recovery calls; Logout(ctx) for logging out; ReleaseDevice(ctx) to release devices.

Python

with connect_launch() as app:
    app.login(email, password)
    result = app.run_feature("export", export_report)

restore() restores existing secure sessions; if there’s none, it shows the login interface. logout() cleans up accounts; release_device() explicitly releases devices. Don’t let synchronous network operations block the desktop event loop.

C# / .NET

await using var app = LaunchConnection.Open();
await app.Login(email, password);
await app.RunFeature("export", async () => {
    await ExportReport();
});

Use await Restore(), await Logout(), and await ReleaseDevice(). Keep the SDK lifecycle alive while the application is running and use asynchronous interface flows.

Java

try (var app = LaunchConnection.open()) {
    app.login(email, passwordChars);
    app.runFeature("export", () -> exportReport());
}

The password uses char[]. restore() returns NO_SESSION failure when there’s no session, and the login screen should be displayed; other failures cannot be considered authorization. logout() and releaseDevice() are different operations. try-with-resources takes care of closing.

JavaScript / Node.js / TypeScript

const app = connectLaunch();
try {
  await app.login(email, password);
  const result = await app.runFeature('export', () => exportReport());
} finally {
  await app.close();
}

restore() returns null when there’s no session; business operations are only allowed after normal recovery. The boolean return value of logout() indicates whether the remote logout is confirmed, and device release failure should show an error. The code runs on Node.js, the Electron main process, or a trusted backend; the browser and Electron renderer process do not save authorization credentials.

Rust

let mut app = connect_launch()?;
app.login(&email, &password)?;
let result = app.run_feature("export", || {
    export_report()?;
    Ok(())
})?;
app.close();

The callback returns Result<T, Failure>. restore(), logout(), and release_device() return results and failures must be handled. Drop also takes care of closing the runtime. By default, the native core is compiled and linked by build.rs, so you don’t need to link the official SDK yourself.

Ruby

app = connect_launch
begin
  app.login(email, password)
  result = app.run_feature('export') { export_report }
ensure
  app.close
end

restore restores the session, logout logs out, release_device releases the device. Protect operations using a code block; exceptions cannot be converted to success.

C

static int export_action(void *context) {
    return export_report(context); /* Return 1 only on success. */
}

launch_application *app = connect_launch();
if (!app) return 0;
int ok = launch_application_login(app, email, password);
if (ok) ok = launch_application_run_feature(app, "export", export_action, context);
/* Check launch_application_error(app) on failure; never log credentials. */
launch_application_close(app);
return ok;

launch_application_restore has three states: 1 restored, 0 no session, -1 failure. Only when there’s no session should the login be displayed normally; denial or exceptions cannot be counted as success. Return values of logout and release_device must also be checked.

CMake only imports Launch:

find_package(LicentivoLaunch CONFIG REQUIRED)
add_executable(myapp main.c)
licentivo_launch_link(myapp)

C++

auto app = connectLaunch();
app.Login(email.c_str(), password.c_str());
app.RunFeature("export", [&] { exportReport(); });

Restore(), Logout(), ReleaseDevice() follow C++ exception semantics. RAII destructors take care of closing. CMake uses licentivo_launch_link(myapp CXX), Launch automatically handles SDK linking and runtime libraries in the distribution package.

Lifecycle, secure storage, and errors

Creating a connection object only completes initialization. The program must be logged in or successfully restored and use protected callbacks for each business operation. Paid orders, existing sessions, or clickable buttons cannot replace SDK verification.

By default, sessions are only stored in memory. Remembering a login requires secure storage: Go, Python, C#, and native C/C++ provide DPAPI for the current Windows user; Java, Node, Rust, and Ruby offer AES-GCM storage using the caller's key. Cross-platform apps should connect to the system credential store. Do not put the key and ciphertext in the same regular directory.

Regular shutdown keeps sessions actively remembered by the user and stops the runtime. When signing out, first call the official SDK for a unified logout, then clear Launch’s own account records. ReleaseDevice is a compatible entry in the same process; do not indicate a successful release if the remote revocation is pending. Do not clean the official SDK’s cache directory or exit recovery logs. Session protection in Launch does not mean all device files of the official SDK are encrypted, so cache directory permissions should be restricted.

Status Program handling
Account or password failure Show a general login failure, without revealing whether the account exists
EMAIL_VERIFICATION_REQUIRED Guide to complete store email verification
ENTITLEMENT_PENDING Show syncing, wait according to limited retries and Retry-After in the package
ENTITLEMENT_NOT_PURCHASED Guide to purchase or switch account
ENTITLEMENT_EXPIRED Guide to renew, do not bypass denial with old credentials
ENTITLEMENT_SUSPENDED Stop protected functions, contact the merchant
Device limit reached Guide to manage or explicitly release devices
Network/HTTP 5xx Only offline licenses verified by the SDK and still valid can be used

Explicit 401/403/404, account mismatch, cancellation, or rate limiting cannot be turned into successful offline authorization. Policies for first activation and offline restrictions still require a network connection. When server domain/IP cannot be accessed, display connection issues; do not secretly connect to other sites.

Acceptance and reference

Verify real login, account authorization, protected operations, restart recovery, valid offline and offline expiration, cache tampering, logout, account switching, and device release. This article does not require using AI. Testing tools and external acceptance boundaries can be found in acceptance.md; local packages and build instructions are in integration-packages.md.

Configuration checks, code generation, and local testing do not automatically prove real payment, authorization issuance, or official website activation success. External stores and payment sandboxes need to be configured and accepted separately.