Skip to content

Getting started

SDKs

Official clients for TypeScript, Python and C++. They wrap the client API, verify every response signature and raise errors that carry the API's stable error code.

Configuration

Every SDK needs exactly two values, both from your application's page in the dashboard:

SDK configuration
FieldTypeDescription
appIdstringYour public app ID, e.g. app_8f2k1x9q. Sent as X-Aroli-App. Safe to ship.
publicKeystringYour application's Ed25519 public key. Pinned in your build; every response signature is verified against it.

TypeScript

Terminal
npm i @aroli/sdk
main.ts
import { Aroli, AroliError } from "@aroli/sdk";

const aroli = new Aroli({
  appId: "app_8f2k1x9q",            // public - safe to ship
  publicKey: "<your app's Ed25519 key>", // pinned: responses are verified
});

try {
  const session = await aroli.login({ username, password, hwid: machineId() });
  await session.redeem(licenseKey);           // binds the key to this user + device
  if (!(await session.hasEntitlement("pro"))) showUpgrade();
  session.startHeartbeat();                   // keeps the session alive
} catch (err) {
  if (err instanceof AroliError && err.code === "device_mismatch") {
    showError("This account is linked to another device.");
  }
}

Python

Terminal
pip install aroli
main.py
from aroli import Aroli, AroliError

aroli = Aroli(app_id="app_8f2k1x9q", public_key="<your app's Ed25519 key>")

try:
    session = aroli.login("alice", password, hwid=machine_id())
    session.redeem(license_key)
    if not session.has_entitlement("pro"):
        show_upgrade()
except AroliError as err:
    if err.code == "license_already_redeemed":
        print("That key has already been used.")

C++

The C++ client is a header (<aroli/aroli.hpp>) that uses libcurl for HTTPS and libsodium for Ed25519 verification. It provides aroli::machine_id() as a convenience for obtaining a hardware ID.

main.cpp
#include <aroli/aroli.hpp>

aroli::Client client{"app_8f2k1x9q", "<your app's Ed25519 key>"};

try {
    auto session = client.login(username, password, aroli::machine_id());
    session.redeem(license_key);
    if (!session.has_entitlement("pro")) show_upgrade();
} catch (const aroli::Error& e) {
    if (e.code() == "activation_limit_reached") show_error(e.what());
}

Sessions and heartbeats

A successful login returns a session holding a bearer token (aus_…). The SDK attaches it to authenticated calls such as redeem and entitlement checks. Calling startHeartbeat() (TypeScript) keeps the session alive via POST /api/v1/client/heartbeat. If a session has expired or was revoked, calls fail with session_expired - sign the user in again.

Error handling

All SDKs raise a single error type (AroliError, or aroli::Error in C++) with a code that matches the API's error codes and a human-readable message. Branch on the code; display the message.

Common error codes in client apps
CodeHTTPMeaning
invalid_credentials401Wrong username or password.
device_mismatch403The account is bound to a different device.
device_limit_reached409No free device slots for this account.
license_already_redeemed409The key has already been used.
activation_limit_reached409The key has no activations left.
entitlement_missing402The user has no active entitlement for the product.
rate_limited429Too many requests - retry after the Retry-After interval.

See the full list of error codes.

Using another language?

The client API is plain HTTPS and JSON. Send X-Aroli-App, optionally a random X-Aroli-Nonce, and verify X-Aroli-Signature yourself - the signature format is documented.