Documentation · SoftActivate Licensing

Quickstart: C++

This quickstart takes about ten minutes. You activate a license from C++, persist it to disk, confirm it validates with no network connection, and release the seat again.

Before you start

From Getting started you should have your vendor id (console → Settings), a license key (issued by an order, Orders → Create, and emailed to the customer), and the installed SDK.

Project setup

The SDK ships a CMake package. The C++ surface consists of header-only wrapper classes, so there is nothing else to link against:

find_package(sws CONFIG REQUIRED)
target_link_libraries(your_app PRIVATE sws::sws)

The whole program

This is a complete, runnable integration: the same loop your application runs on every start.

#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>

#include "softactivate/sws_licensing.h"

// load a previously saved license, if any - after the first (online) activation,
// every later start validates this file with no network access at all
static std::unique_ptr<sws::licensing::license> load_license()
{
    std::ifstream file("license.dat");
    if (!file)
        return nullptr;

    std::stringstream buffer;
    buffer << file.rdbuf();
    return std::make_unique<sws::licensing::license>(buffer.str().c_str());
}

int main()
{
    try
    {
        auto client = sws::licensing::client::create("https://lm.sws.softactivate.com");

        client->set_metadata("trusted_domain", "sws.softactivate.com");

        // your tenant coordinates - vendor id from the console (Settings),
        // license key from your order's delivery email
        client->set_vendor_id("YOUR-VENDOR-ID");
        client->set_license_key("XXXXX-XXXXX-XXXXX-XXXXX-XXXXX");

        // your product's Reference Id (console -> Products): a key for a
        // different product is refused - see the product binding guide
        client->set_product_id("YOUR_PRODUCT_ID");

        // validate: with no stored license this activates the device (online, once);
        // with a stored license it verifies the certificate chain, the device
        // fingerprint and the dates locally - and renews online only when needed
        auto params = client->create_license_validation_params();

        auto license = load_license();
        if (license)
            params->set_license(license);

        auto result = client->validate_license(params);

        if (!result->is_license_valid())
        {
            // the precise status says WHY - expired, revoked, bound to another
            // machine, subscription lapsed... each deserves different UX; see the
            // statuses reference: /licensing/docs/status-codes/
            std::cerr << "License is not valid (status " << result->get_status() << ")\n";
            return 1;
        }

        // persist the new or renewed certificate whenever one is issued
        if (auto updated = result->get_updated_license())
            std::ofstream("license.dat") << updated->serialize();

        std::cout << "License is valid.\n";
        return 0;
    }
    catch (const std::exception& ex)
    {
        std::cerr << "Licensing error: " << ex.what() << "\n";
        return 1;
    }
}

Replace the vendor id and license key with yours, put deployment-root.crt next to the binary (in your real product, embed it or install it with your application), and run it.

Run it three times

  1. First run (online): no license.dat exists, so validate_license activates the device with the service. The SDK receives the license and the program saves it to license.dat.
  2. Second run (disconnect the network if you like): the stored license is verified entirely on the machine, and no network access happens. This is the everyday path your customers' machines take on every start.
  3. Moving on: when you are done with this machine, release its seat so the key can activate elsewhere:
client->deactivate_license();
std::remove("license.dat"); // the local file is now meaningless

When validation says no

A false result from is_license_valid() can mean several different things. get_status() tells you whether the license is expired, revoked, bound to a different device, or waiting on a lapsed subscription, and each case deserves different UX. The statuses and errors reference maps every status to a recommended action.

If your codebase is C rather than C++, the headers also expose the underlying interface directly: sws_* structs and the sws_licensing_client_create factory function. The wrapper classes are optional if your integration layer prefers working at that level.

Next: the .NET quickstart, or go deeper on getting started in the console.