---
slug: "/docs/v1/integration-guide/activate"
title: "Activate your first license"
description: "Stage 7: activate your first license with a clear outcome, verification steps and one next action."
section: "Integration Guide"
order: 22
audience: "all"
level: "beginner"
last_updated: "2026-10-20"
version: "v1"
related: []
draft: false
layout: "guide"
---
## What you will do
Save one complete file and run it. It also supports later validate, check and deactivate actions. Keep this file through Stages 8–13.
:::tabs
:::tab python Python
Save **license-check.py** in your example folder.
```python
"""Sandbox learning example; use private state, never a developer API key."""
import os
import sys
from pathlib import Path
from kdpika_licensing import LicenseClient

try:
    action = sys.argv[1] if len(sys.argv) == 2 else "activate"
    if action not in ("activate", "validate", "check", "deactivate"):
        raise ValueError("Choose an action")
    client = LicenseClient(
        product=os.environ["KDP_APP_ID"], environment="SANDBOX",
        base_url=os.getenv("KDP_BASE_URL", "https://licensing.kdpika.com"),
        storage_dir=Path(os.environ["KDP_STATE_DIR"]), prefer_keyring=False)
    result = client.activate(os.environ["KDP_LICENSE_KEY"],
        os.getenv("KDP_CUSTOMER_EMAIL") or None) if action == "activate" else getattr(client, action)()
    released = action == "deactivate" and result.valid
    allowed = action != "deactivate" and result.valid and result.signature_valid
    print("Device released." if released else "Sandbox license verified." if allowed
          else "License could not be confirmed. Check your key or contact support.")
    sys.exit(0 if released or allowed else 1)
except Exception:
    print("License check unavailable. Check configuration and connection.", file=sys.stderr)
    sys.exit(2)
```
Run:
```bash
.venv/bin/python license-check.py activate
```
:::
:::tab javascript JavaScript / Node.js
Save **license-check.mjs** in your example folder.
```javascript
// Node.js / Electron main process, not browser JavaScript.
import { LicenseClient } from '@kdpika/license-sdk';
try {
  const action = process.argv[2] || 'activate';
  if (!['activate', 'validate', 'check', 'deactivate'].includes(action)) throw Error();
  const client = new LicenseClient({
    product: process.env.KDP_APP_ID, environment: 'SANDBOX',
    baseUrl: process.env.KDP_BASE_URL || 'https://licensing.kdpika.com',
    storageDir: process.env.KDP_STATE_DIR
  });
  if (!process.env.KDP_STATE_DIR) throw Error();
  const result = action === 'activate'
    ? await client.activate(process.env.KDP_LICENSE_KEY, process.env.KDP_CUSTOMER_EMAIL || null)
    : await client[action]();
  const released = action === 'deactivate' && result.valid;
  const allowed = action !== 'deactivate' && result.valid && result.signatureValid;
  console.log(released ? 'Device released.' : allowed ? 'Sandbox license verified.'
    : 'License could not be confirmed. Check your key or contact support.');
  process.exitCode = released || allowed ? 0 : 1;
} catch {
  console.error('License check unavailable. Check configuration and connection.');
  process.exitCode = 2;
}
```
Run:
```bash
node license-check.mjs activate
```
:::
:::tab php PHP
Save **license-check.php** in your example folder.
```php
<?php
declare(strict_types=1);
use KDPika\LicenseSdk\LicenseClient;
try {
    require (getenv('KDP_SDK_DIR') ?: './kdpika-php-sdk').'/vendor/autoload.php';
    $action = $argv[1] ?? 'activate';
    if (!in_array($action, ['activate','validate','check','deactivate'], true)
        || !getenv('KDP_APP_ID') || !getenv('KDP_STATE_DIR')) throw new RuntimeException();
    $client = new LicenseClient(product:getenv('KDP_APP_ID'), environment:'SANDBOX',
        baseUrl:getenv('KDP_BASE_URL') ?: 'https://licensing.kdpika.com',
        storageDir:getenv('KDP_STATE_DIR'));
    $result = $action === 'activate'
        ? $client->activate(getenv('KDP_LICENSE_KEY') ?: '', getenv('KDP_CUSTOMER_EMAIL') ?: null)
        : $client->$action();
    $released = $action === 'deactivate' && $result->valid;
    $allowed = $action !== 'deactivate' && $result->valid && $result->signatureValid;
    echo $released ? 'Device released.' : ($allowed ? 'Sandbox license verified.'
        : 'License could not be confirmed. Check your key or contact support.'), PHP_EOL;
    exit($released || $allowed ? 0 : 1);
} catch (Throwable) {
    fwrite(STDERR, 'License check unavailable. Check configuration and connection.'.PHP_EOL);
    exit(2);
}
```
Run:
```bash
php license-check.php activate
```
:::
:::tab csharp C# / .NET
Save **Program.cs** in your example folder.
```csharp
using KDPika.LicenseSdk;
static string Required(string name) => Environment.GetEnvironmentVariable(name)
    is string value && value.Length > 0 ? value : throw new ArgumentException();
try {
    var action = args.Length == 0 ? "activate" : args[0];
    if (!new[]{"activate","validate","check","deactivate"}.Contains(action)) throw new ArgumentException();
    var client = new LicenseClient(Required("KDP_APP_ID"), "SANDBOX",
        Environment.GetEnvironmentVariable("KDP_BASE_URL") ?? "https://licensing.kdpika.com",
        storageDir:Required("KDP_STATE_DIR"));
    var result = action switch {
        "activate" => await client.ActivateAsync(Required("KDP_LICENSE_KEY"),
            Environment.GetEnvironmentVariable("KDP_CUSTOMER_EMAIL")),
        "validate" => await client.ValidateAsync(), "check" => await client.CheckAsync(),
        _ => await client.DeactivateAsync()
    };
    var released = action == "deactivate" && result.Valid;
    var allowed = action != "deactivate" && result.Valid && result.SignatureValid;
    Console.WriteLine(released ? "Device released." : allowed ? "Sandbox license verified."
        : "License could not be confirmed. Check your key or contact support.");
    Environment.ExitCode = released || allowed ? 0 : 1;
} catch {
    Console.Error.WriteLine("License check unavailable. Check configuration and connection.");
    Environment.ExitCode = 2;
}
```
Run:
```bash
dotnet run --project Guide.csproj -- activate
```
:::
:::tab curl cURL / REST clients
Use the cURL transport flow in the install stage, then the selected REST project's [activation](/docs/v1/start/glossary#activation) command. It is not an [official SDK](/docs/v1/start/glossary#official-sdk); do not grant access until signature and semantic checks pass. [Browse all REST projects](/docs/v1/sdks/overview).
:::
:::
## Expected result
For a valid fresh activation, standard output is exactly:
```text
Sandbox license verified.
```
The program exits with code 0. In the dashboard, open **[Devices](/docs/v1/start/glossary#device)** or the [license](/docs/v1/start/glossary#license)'s **Devices** count: one installation is active. The sample never prints a token or full key.
## If it does not work
| What you see | What to do |
|---|---|
| INVALID_LICENSE | Check the full key, [public App ID](/docs/v1/start/glossary#public-app-id), [Sandbox](/docs/v1/start/glossary#sandbox) selection and matching [customer](/docs/v1/start/glossary#customer) email. |
| MAX_DEVICES_REACHED | Deactivate an old installation or inspect Devices. Do not make random identities. |
| SIGNATURE_INVALID / cached signature error | Keep access locked. Check the runtime, clock and SDK compatibility notes; do not disable verification. |
| NOT_ACTIVATED | Run activate in the same private state directory first. |
| NETWORK_ERROR / no connection | Reconnect. A first activation needs internet; no cached response means no offline grant. |
| LICENSE_EXPIRED / LICENSE_REVOKED / LICENSE_SUSPENDED | Explain the state to the customer and provide support; never silently convert it to valid. |
## Stage checklist
- My chosen sample ran against Sandbox.
- I checked the active device in the dashboard.
- I did not unlock [features](/docs/v1/start/glossary#feature) on an unverified answer.

## Next steps
[Continue to Stage 8: Validate when your app starts](/docs/v1/integration-guide/validate)
