# 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 ](/en/launch-documents/external-licensing/), 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 ](/en/launch-documents/account-purchase-boundary/). 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:

```text
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](https://github.com/spf86/licentivo-launch-sdk/releases/tag/v0.1.6) also provides native packages and offline files; usage instructions see [download package installation instructions ](/en/launch-documents/integration-packages/#install-a-downloaded-distribution).

| 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](https://github.com/spf86/licentivo-launch-sdk/releases/tag/v0.1.6), 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](https://github.com/spf86/licentivo-launch-sdk), native packages and offline files can be found at [v0.1.6 Release](https://github.com/spf86/licentivo-launch-sdk/releases/tag/v0.1.6), and public installation results are at [Registry verification in nine languages](https://github.com/spf86/licentivo-launch-sdk/blob/main/docs/registry-verification.json). 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

```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

```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

```csharp
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

```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

```javascript
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

```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

```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

```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:

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

### C++

```cpp
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](/en/launch-documents/acceptance/); local packages and build instructions are in [integration-packages.md](/en/launch-documents/integration-packages/).

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.
