Activation Service
The Magic Lane Activation Service API is a C++ interface for securely activating licenses in Magic Lane SDK-based products. It simplifies the process of license distribution, activation, validation, and revocation - supporting both online and offline activation workflows.
Supported Scenarios
Currently supported activation scenarios:
- One-time license activation.
- Automatic license renewal.
- Device-bound licenses.
Purpose
This manual provides comprehensive documentation for integrating the Activation Service API. It includes:
- API endpoints.
- Request/response formats.
- Authentication requirements.
- Error codes.
- Example use cases.
Key Features
- License Activation: Activate a license with a simple API call.
- License Validation: Check if a license key is valid and active.
- Device Binding: Licenses are bound to the activating device.
Intended Audience
- Backend and frontend developers integrating the API.
- QA engineers automating license tests.
- Support engineers handling license activation issues.
Prerequisites
To use this API, you should have:
- Basic understanding of HTTP and REST APIs.
- Familiarity with tools like Postman, curl, or HTTP clients.
- A developer account on Magic Lane platform.
- A valid Application Id for testing or production.
Getting Started
The C++ Activation Service wraps around the underlying Activation REST API. It abstracts the communication, making it simple to trigger activation with just a function call.
Scenario 1: Device with Internet Connection
This is the simplest and most common scenario.
Steps:
- Obtain the Application Id which is allowed to issue license keys.
- Implement the
gem::IProgressListenerinterface (for tracking progress). - Get an instance of
gem::ActivationService. - Call
activate()on the instance. - Wait for
notifyCompletefrom the progress listener. - If the returned error code is
gem::KNoError, activation is completed.
Function signature:
int activate(
ProgressListener listener,
const gem::String& applicationId,
const gem::String& licenseKey,
const gem::String& productId = gem::ProductID::CORE
);
Parameter details:
listener– your implementation ofgem::IProgressListener.applicationId– id obtained from Magic Lane platform.licenseKey– The unique UUID v4 string which was previously bought for theproductIdor was previously generated usinggenerateLicenseKey()method.productId- (Optional) Product to activate. Defaults toCORE. It must match the productId that the license key is bound to.
Important: Keep the
licenseKey. It's essential for restoring or migrating activations later.
Scenario 2: Device without Internet Connection
On devices with no Internet (e.g., embedded devices), activation requires an external step using a mobile app.
Steps:
-
Call
activate(). It will returngem::error::KRequiredand a Base64 blob innotifyComplete. -
Display the Base64 blob as a QR code on the device screen.
-
Use the Activation Companion App to scan the QR code.
-
The app will:
- Make an HTTP request to:
https://m71os.services.magicearthsdk.com/services_list_json- Find the URL for Service ID 3.
- Append to the found URL:
/services/tokens/v1/activations- Send a POST request with:
{ "request_blob": "<Base64_blob>" }- Receive a 20-character
offline_activation_key. - Display it on the mobile screen.
-
User inputs the key using the device touchscreen.
-
Call
completeOfflineActivation(“<20-char-key>”)on yourgem::ActivationServiceinstance. -
Activation completes.
Scenario 3: Assisted Activation via Payment Flow (Activation Request + Polling)
This scenario allows applications to initiate license activation for products that have not yet been purchased. It’s designed for devices that are online, but where the user interaction (e.g., purchasing a license) happens outside the app - usually via QR code and mobile browser.
This is the preferred flow for enabling fast and user-friendly license purchases directly from within the app interface.
Steps:
-
The app sends a POST request to:
POST /services/tokens/v1/activations/requestRequest body example:
{
"application_id": "a2c3ea17-e041-4867-a663-a6006224e457",
"product_id": "core-yearly"
}Response example:
{
"request_code": "52a9d591842e4f68b7bacfa0ba920e28",
"url": "https://pay.example.com/activate?request_code=52a9d591842e4f68b7bacfa0ba920e28"
}- The app should generate a QR code for the returned URL and show it to the user.
- This link points to the secure hosted payment/checkout page.
-
While the user is completing the payment, the app should start polling for the license key:
GET /services/tokens/v1/activations/poll?request_code=52a9d591842e4f68b7bacfa0ba920e28Possible responses:
-
200 OKwith payload:{
"license_key": "5dc97096-3eff-488b-9c4d-66645dd4fa39"
}The license key has been issued and can now be used in the standard
activate()call. -
204 No Content→ The request exists but is not yet fulfilled (waiting for payment). -
404 Not Found→ Therequest_codewas invalid or expired.
-
-
Once
license_keyis received, call:activationService.activate(listener, applicationId, licenseKey, productId);This follows the same process as Scenario 1 and completes the license activation locally.
Notes
- Each activation request has an expiration timestamp (default: 15 minutes), but the system allows fulfillment slightly after expiry in case the user is delayed.
- Expired and unfulfilled requests are cleaned up periodically by the backend.
- This flow is fully supported by the C++ SDK - the
activationService.activate(...)call is used after retrieving thelicenseKeyfrom the polling endpoint.
3. Restore or Migrate Activation
To migrate a license (e.g., to a new device), you must first call deactivate() from the device on which it is active with matching parameters:
- Same
applicationId. - Same
licenseKey. - Same
productId.
If all conditions are met, the original activation is deactivated and now you are able to activate the license key on a new device.
In case deactivate() returns gem::error::KRequired either try again when having an internet connection or follow a similar flow like in Scenario 2:
Steps:
-
Call
deactivate(). It will returngem::error::KRequiredand a Base64 blob innotifyComplete. -
Display the Base64 blob as a QR code on the device screen.
-
Use the Activation Companion App to scan the QR code.
-
The app will:
- Make an HTTP request to:
https://m71os.services.magicearthsdk.com/services_list_json- Find the URL for Service ID 3.
- Append to the found URL:
/services/tokens/v1/activations- Send a DELETE request with:
{ "request_blob": "<Base64_blob>" }- Receive a 20-character
offline_deactivation_key. - Display it on the mobile screen.
-
User inputs the key using the device touchscreen.
-
Call
completeOfflineDeactivation(“<20-char-key>”)on yourgem::ActivationServiceinstance.
Deactivation completes.
Once the deactivate() call is initiated, the license from the device enters a “PendingDeactivation” state which makes it no longer usable until the QR code is scanned by the Activation Companion App with success.
The offline_deactivation_key is for cleanup purposes of the old device. The license key is already usable after the successful QR scan.