Skip to main content

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:

  1. Obtain the Application Id which is allowed to issue license keys.
  2. Implement the gem::IProgressListener interface (for tracking progress).
  3. Get an instance of gem::ActivationService.
  4. Call activate() on the instance.
  5. Wait for notifyComplete from the progress listener.
  6. 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 of gem::IProgressListener.
  • applicationId – id obtained from Magic Lane platform.
  • licenseKey – The unique UUID v4 string which was previously bought for the productId or was previously generated using generateLicenseKey() method.
  • productId - (Optional) Product to activate. Defaults to CORE. 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:

  1. Call activate(). It will return gem::error::KRequired and a Base64 blob in notifyComplete.

  2. Display the Base64 blob as a QR code on the device screen.

  3. Use the Activation Companion App to scan the QR code.

  4. 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.
  5. User inputs the key using the device touchscreen.

  6. Call completeOfflineActivation(“<20-char-key>”) on your gem::ActivationService instance.

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

  1. The app sends a POST request to:

    POST /services/tokens/v1/activations/request

    Request 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.
  2. While the user is completing the payment, the app should start polling for the license key:

    GET /services/tokens/v1/activations/poll?request_code=52a9d591842e4f68b7bacfa0ba920e28

    Possible responses:

    • 200 OK with 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 → The request_code was invalid or expired.

  3. Once license_key is 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 the licenseKey from 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:

  1. Same applicationId.
  2. Same licenseKey.
  3. 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:

  1. Call deactivate(). It will return gem::error::KRequired and a Base64 blob in notifyComplete.

  2. Display the Base64 blob as a QR code on the device screen.

  3. Use the Activation Companion App to scan the QR code.

  4. 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.
  5. User inputs the key using the device touchscreen.

  6. Call completeOfflineDeactivation(“<20-char-key>”) on your gem::ActivationService instance.

Deactivation completes.

warning

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.