C++ SDK
C++ SDK
C++17 static library. The external dependencies are libcurl and OpenSSL — no JSON library required. JSON fields are extracted using targeted string search so the dependency tree stays minimal. Built with CMake 3.14+.
Download C++ SDK (ZIP)Building — Linux / macOS
# Ubuntu / Debian sudo apt-get install libcurl4-openssl-dev libssl-dev # macOS (Homebrew) brew install curl openssl cd SDKs/cpp cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build
Building — Windows (vcpkg + Visual Studio)
vcpkg install curl:x64-windows openssl:x64-windows
cmake -B build `
-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build --config ReleaseIntegrating into your CMake project
add_subdirectory(SDKs/cpp) target_link_libraries(your_target PRIVATE permitcore)
Quick start
#include <permitcore/permit_client.hpp> #include <iostream> int main() { permitcore::PermitClient client("https://api.permitcore.dev"); auto result = client.validate("PERMIT-XXXX-XXXX-XXXX-XXXX"); if (result.is_valid) { std::cout << "License OK — product: " << result.product_name << "\n"; if (result.is_offline) std::cout << "Running on a cached result — server was unreachable.\n"; } else { std::cerr << "License rejected: " << result.message << "\n"; } }
validate() and activate() never throw for a network failure — they fall back to the local offline-grace cache automatically and, failing that, return is_valid: false with is_offline: true. Only meter() throws PermitException.
Validate with version check
auto result = client.validate("PERMIT-XXXX-XXXX-XXXX-XXXX", "2.3.1"); if (!result.is_valid && !result.min_version.empty()) show_error("Upgrade required: minimum version is " + result.min_version);
Activation
permitcore::ActivateOptions opts; opts.device_id = "sha256-of-mac-plus-board-serial"; opts.device_name = "My-Linux-Server"; opts.version = "2.3.1"; auto result = client.activate("PERMIT-XXXX-XXXX-XXXX-XXXX", opts); if (result.is_valid) { std::cout << "Activated successfully.\n"; } else { std::cerr << "Activation failed: " << result.message << "\n"; }
Metered billing
auto m = client.meter("PERMIT-XXXX-XXXX-XXXX-XXXX", "export", 1); if (m.recorded) std::cout << "Usage recorded.\n"; // Batch — 5 API calls at once auto m2 = client.meter("PERMIT-XXXX-XXXX-XXXX-XXXX", "api_call", 5);
ValidateResult struct fields
| Field | Type | Description |
|---|---|---|
is_valid | bool | true if the license is active and all checks pass |
product_name | std::string | Product name |
remaining_activations | int | Remaining activation seats (0 = at limit) |
expires_at | std::string | ISO 8601 expiry timestamp; empty if perpetual |
message | std::string | Status message from the server |
vendor_warning | std::string | Non-empty if the vendor's PermitCore plan is lapsing |
features | std::vector<std::string> | Enabled feature flags |
custom_fields | std::map<std::string, std::string> | Vendor-defined metadata |
is_trial | bool | true if this is a trial license |
trial_days_remaining | int | Days remaining in the trial |
node_locked | bool | true if HWID node-locking is enabled |
offline_grace_days | int | Days the software may run without a server check |
min_version | std::string | Minimum required software version; empty if unrestricted |
max_version | std::string | Maximum allowed software version; empty if unrestricted |
is_offline | bool | true when this result was served from the local offline-grace cache (server unreachable) |
ActivateOptions struct
| Field | Description |
|---|---|
device_id | Hardware fingerprint — SHA-256 of MAC address, motherboard serial, or similar stable identifier |
device_name | Human-readable label shown in the admin activation history |
version | Current software version string, e.g. "2.3.1" |
Offline grace period (built in)
When offline_grace_days is set on the license, validate()/activate() cache every successful result to the OS temp directory (%TEMP% on Windows, $TMPDIR//tmp on POSIX). If a later call can't reach the server, the cached result is returned automatically — check is_offline to detect it. Disable via the third constructor argument: permitcore::PermitClient client(base_url, 10, false);.
Implementation notes
- No JSON library. Fields extracted from responses (including the cache file) using
std::string::find— the client also links OpenSSL for signature verification. - Thread safety. Each method call creates and destroys its own curl easy handle. Safe to call from multiple threads on a shared
PermitClientinstance. - Custom timeout. Default is 10 seconds. Pass a second argument:
permitcore::PermitClient client("https://...", 5);for 5 seconds. - HTTPS on Windows. Build against the WinSSL backend (
CURL_USE_SCHANNEL) for zero-config HTTPS without deploying a CA bundle.