KDPika Licensing Sign inStart free
API v1
Show all languages
Browse documentation

Choose a page in the navigation drawer.

KDPika Licensing · API v1 Intermediate

Errors and safe user messages

Handle every current licensing error, distinguish SDK-local and operational codes, and give users a safe next step.

On this page
Updated 2026-10-17 UTCDownload Markdown

Use error.code for decisions and a clear, non-technical message for users; never infer a license from an HTTP status alone.

What you will learn

  • Recognize all current API/router codes and the separate SDK/web namespaces.
  • Handle refusal without leaking credentials or enabling features.
  • Use request IDs with support.

Prerequisites

Error envelope

Licensing API failures use the actual non-2xx HTTP status and this shape. This is a real invalid-token capture with a synthetic request ID:

jsonjson
{"success":false,"error":{"code":"INVALID_TOKEN","message":"The activation token is invalid."},"request_id":"req_000000000000000000000000"}

SDK result objects instead expose valid/Valid, error_code/errorCode/ErrorCode, message and request_id/requestId/RequestId. A local result has no HTTP response. Operational/billing endpoints can use a string error field without this envelope. Do not apply their status codes or Retry-After headers to licensing requests.

A known code can occur in more than one namespace: INVALID_LICENSE and LICENSE_EXPIRED can also be SDK-local, while FORBIDDEN/RATE_LIMITED/NOT_FOUND are reused by unrelated web routes. Preserve the operation and source as well as the code.

Licensing API and router

CodeHTTP or localMeaning / common causesFix and retry ruleWhere it is returnedSuggested end-user message
ACTIVATION_LIMIT_REACHED409New/inactive installation while activation_count >= max_activationsDeveloper adjusts policy; reset-devices does not zero countactivateThis license has reached its device or activation limit. Contact the software developer for help.
APP_VERSION_NOT_SUPPORTED403Nonempty activation app_version outside configured rangeUse supported versionactivateThis version of the application is not covered by your license. Install a supported version.
DEVICE_LIMIT_REACHED409New/inactive installation while active seats >= license.max_devicesDeactivate/reset a seatactivateThis license has reached its device or activation limit. Contact the software developer for help.
DEVICE_MISMATCH403Provided installation ID does not match token-bound HMAC hashUse original installation; do not copy tokenvalidatePlease activate this installation again with your license details.
DEVICE_NOT_AUTHORIZED403Token is active but associated device is not ACTIVEReactivation if eligiblevalidatePlease activate this installation again with your license details.
FORBIDDEN403Developer scope missing; checkout account role not OWNER/ADMINUse authorized scope/rolecreate, get, revoke, suspend, restore, renew, reset-devicesYour account connection needs attention. Please contact the software developer.
IDEMPOTENCY_CONFLICT409Organization key reused with different decoded-body hash (member order matters)Use same body; new key only for new operationcreateThis request differs from an earlier request. Please contact support before trying again.
INTERNAL_ERROR500Uncaught exception at global boundarySafe retry only for idempotent operation; preserve request_idpublic-key, create, activate, validate, deactivate, get, revoke, suspend, restore, renew, reset-devicesWe could not complete this request. Please try again later or contact support if it continues.
INVALID_API_KEY401Missing/invalid/revoked key or prohibited subscription/environmentReplace/configure keycreate, get, revoke, suspend, restore, renew, reset-devicesYour account connection needs attention. Please contact the software developer.
INVALID_LICENSE404Activation key/product/environment/customer email mismatch; SDK empty key local error has no HTTPCorrect detailsactivateWe could not activate these license details. Check your key and email, then try again.
INVALID_REQUEST422Input constraints or entitlement/resource/renewal domain rejectionCorrect input/plan; not blind retrycreate, activate, validate, renew, reset-devicesSome information or account settings need attention. Check your details or contact support.
INVALID_STATE409Forbidden state transition or restore with elapsed expiryResolve state/renew firstrevoke, suspend, restoreThis change is not available for the current license. Please contact the software developer.
INVALID_TOKEN401Missing/non-act_/unknown/revoked/deactivated activation tokenReactivate eligible installationvalidate, deactivatePlease activate this installation again with your license details.
LICENSE_CANCELLED403License CANCELLED and no elapsed deadline taking precedenceDo not retry; new eligible licenseactivate, validateThis license is no longer available. Please contact the software developer.
LICENSE_EXPIRED403Elapsed expires_at before state check; or EXPIRED state; SDK local expiry has no HTTPRenew eligible licenseactivate, validateYour license has expired. Contact the software developer to renew it.
LICENSE_NOT_FOUND404Management scoped license absentCorrect org/product/environment/IDget, revoke, suspend, restore, renew, reset-devicesWe could not find the requested license or plan. Please contact the software developer.
LICENSE_PENDING403License PENDING and no elapsed deadline taking precedenceWait for authorized activationactivate, validateThis license is not ready to use. Please contact the software developer.
LICENSE_REVOKED403License REVOKED and no elapsed deadline taking precedenceDo not retry; contact developeractivate, validateThis license is no longer available. Please contact the software developer.
LICENSE_SUSPENDED403License SUSPENDED and no elapsed deadline taking precedenceRestore then reactivateactivate, validateThis license is not ready to use. Please contact the software developer.
NOT_FOUND404Unregistered API route/wrong method; or protected operational guard mismatchCorrect path/method/token; no blind retryGlobal API router (unknown path or wrong method); separate guarded operational routesThis request is not available. Please contact support.
PLAN_NOT_FOUND404Create product/plan does not resolve within active API-key productCorrect scoped IDscreateWe could not find the requested license or plan. Please contact the software developer.
RATE_LIMITED429Bucket exhausted; wait for window reset; no licensing Retry-After headerAfter window; apply jitterpublic-key, create, get, revoke, suspend, restore, renew, reset-devices, activate, validateToo many requests were sent. Please wait a minute before trying again.

SDK-local and transport results

CodeHTTP or localMeaning / common causesFix and retry ruleWhere it is returnedSuggested end-user message
CLOCK_ROLLBACK_DETECTEDlocalClock is >300 seconds behind saved/server trusted checkpointCorrect clock then validateNo API-v1 emitter; SDK/web/operational namespaceYour device clock needs attention. Set the correct date and time, then connect to check your license.
HTTP_ERRORlocal / inherited HTTPNon-success remote response without structured licensing error; fallback SDK codeInspect actual status; no automatic blind retryNo API-v1 emitter; SDK/web/operational namespaceWe could not complete this request. Please try again later or contact support if it continues.
INVALID_RESPONSElocalMalformed JSON or missing token/envelope in SDK responseReconnect/contact supportNo API-v1 emitter; SDK/web/operational namespaceWe could not safely confirm your license. Connect again or contact the software developer.
LICENSE_NOT_ACTIVElocalSDK verified payload status is not activeCheck account/license stateNo API-v1 emitter; SDK/web/operational namespaceThis license is not ready to use. Please contact the software developer.
NETWORK_ERRORlocalSDK activation/deactivation transport failure; check may instead use offline cacheRetry connectivity, do not bypass verificationNo API-v1 emitter; SDK/web/operational namespaceConnect to the internet to check your license, then try again.
NOT_ACTIVATEDlocalSDK has no stored token for check/deactivateActivateNo API-v1 emitter; SDK/web/operational namespacePlease activate this installation again with your license details.
OFFLINE_CACHE_INVALIDlocalCached envelope cannot verify; SDK removes itOnline validation; investigate tampering or known canonical defectNo API-v1 emitter; SDK/web/operational namespaceWe could not safely confirm your license. Connect again or contact the software developer.
OFFLINE_CACHE_MISSINGlocalTransport fallback without stored signed cacheOnline validationNo API-v1 emitter; SDK/web/operational namespaceConnect to the internet to check your license, then try again.
OFFLINE_GRACE_EXPIREDlocalCache/offline grace missing or now beyond signed deadlineOnline validationNo API-v1 emitter; SDK/web/operational namespaceConnect to the internet to check your license, then try again.
SIGNATURE_INVALIDlocalSDK signature/envelope/key/product/environment/installation verification exceptionFail closed; investigate key/canonicalizationNo API-v1 emitter; SDK/web/operational namespaceWe could not safely confirm your license. Connect again or contact the software developer.

Other web and operational namespaces

CodeHTTP or localMeaning / common causesFix and retry ruleWhere it is returnedSuggested end-user message
BACKUP_FAILED500Backup exceptionOperator investigatesNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
CHECKOUT_UNAVAILABLE409Checkout creation DomainExceptionResolve account/order then retryNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
CRON_FAILED500Cron exceptionOperator investigatesNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
INSTALLER_LOCKED410Installer lock existsNo public retry; installation already lockedNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
INSTALL_FAILED500Installer exceptionOperator investigates; not public APINo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
INVALID_CSRF419JSON request through CSRF middleware has invalid session token; not currently API-v1 middlewareRefresh session tokenNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
INVALID_EVENT400Stripe event domain validation failureInvestigate account/event bindingNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
INVALID_JSON400Stripe webhook malformed JSON/provider unexpected valueCorrect event; do not retry identical malformed payloadNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
INVALID_SIGNATURE400Stripe webhook missing secret or invalid signatureCorrect configuration; reject untrusted eventNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
METHOD_NOT_ALLOWED405Installer called with non-POSTOperational only; correct methodNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
MIGRATION_FAILED500Migration exceptionOperator investigatesNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
PROCESSING_FAILED500Stripe event unexpected processing failureProvider delivery retry is appropriateNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
PROVISION_FAILED500Admin provisioning exceptionOperator investigatesNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
SDK_NOT_FOUND404Authenticated download requested unsupported languageCorrect languageNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
SDK_UNAVAILABLE503SDK directory/archive temporary failureRetry laterNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.
STRIPE_UNAVAILABLE503Checkout creation unexpected exceptionRetry after 10sNo API-v1 emitter; SDK/web/operational namespaceThis service action could not be completed. Please contact support at hi@kdpika.com.

Retry decisions

RATE_LIMITED: wait a full 60-second licensing window plus jitter when no previous reset time is available. Authentication/input/state/signature errors require correction, not blind retries. Network/500 errors after mutations are uncertain outcomes: reconcile creation/renewal before another write. HTTP_ERROR is a fallback, not proof that an upstream error is safe to retry. Unknown future codes fail closed.

PRODUCT_NOT_FOUND and DEVICE_NOT_FOUND appeared in older documentation but have no current API-v1 emitter. They are not supported error promises.

Safe handling in every official SDK language

These complete programs call the unchanged SDK check() equivalent. An invalid result never enables a feature. Messages/actions come from one adjacent policy.json, so the four languages use the same text. The full self-test mode uses actual result models with synthetic inputs; it does not claim to reproduce48 runtime emitters. The separate API contract tests reproduce the 22 licensing/router codes.

The exact shared policy.json is in the complete example archive; its48 messages/actions match the full table above. Keep that dependency beside the executable sample instead of inventing a second mapping.

Python

python.pypython
"""Safe SDK error UX, Python3.9+ / official Python SDK1.0.0.
Run: python3 python.py (KDP_APP_ID, KDP_STATE_DIR, optional KDP_BASE_URL origin).
Self-test: python3 python.py --self-test < cases.json; real result model, no network.
Output: valid/message/action/request_id only; never raw payload, key or token.
"""
import json
import os
import re
import sys
from pathlib import Path
from license_sdk import LicenseClient
from license_sdk.models import LicenseResult

POLICY=json.loads(Path(__file__).with_name('policy.json').read_text())
def explain(result):
    # Check valid first. A feature helper alone is not an access check.
    entry={'message':'Your license is ready.','action':'continue'} if result.valid else POLICY['codes'].get(result.error_code,POLICY['fallback'])
    request_id=result.request_id if isinstance(result.request_id,str) and re.fullmatch(r'req_[a-f0-9]{24}',result.request_id) else None
    return {'valid':result.valid,'message':entry['message'],'action':entry['action'],'request_id':request_id}

def main():
    if sys.argv[1:]==['--self-test']:
        rows=json.load(sys.stdin)
        for row in rows:
            result=LicenseResult(valid=row['valid'],source='synthetic contract',error_code=row.get('code'),request_id=row.get('request_id'))
            print(json.dumps(explain(result)))
        return
    if len(sys.argv)!=1:raise ValueError('Unknown 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.check(force_online=False)
    print(json.dumps(explain(result)))

if __name__=='__main__':
    try:main()
    except Exception:
        print('The license check is unavailable. Check configuration or contact the software developer.',file=sys.stderr);sys.exit(2)

JavaScript

javascript.mjsjavascript
// Safe SDK error UX. Node18.20+, official JavaScript SDK1.0.0, trusted runtime only.
// Run: node javascript.mjs; KDP_APP_ID/KDP_STATE_DIR, optional KDP_BASE_URL site origin.
// --self-test reads synthetic cases from stdin and uses actual SDK result objects.
// Output: safe UX/request ID only; no raw payload, key or token.
import fs from 'node:fs';
import {LicenseClient,LicenseResult} from '@kdpika/license-sdk';
const policy=JSON.parse(fs.readFileSync(new URL('./policy.json',import.meta.url),'utf8'));
export function explain(result){
  const entry=result.valid?{message:'Your license is ready.',action:'continue'}:policy.codes[result.errorCode]||policy.fallback;
  const requestId=typeof result.requestId==='string'&&/^req_[a-f0-9]{24}$/.test(result.requestId)?result.requestId:null;
  return {valid:result.valid,message:entry.message,action:entry.action,request_id:requestId};
}
try {
  if(process.argv.slice(2).join(' ')==='--self-test'){
    const rows=JSON.parse(fs.readFileSync(0,'utf8'));
    for(const row of rows)console.log(JSON.stringify(explain(new LicenseResult({valid:row.valid,source:'synthetic contract',errorCode:row.code,requestId:row.request_id}))));
  }else{
    if(process.argv.length!==2)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});
    console.log(JSON.stringify(explain(await client.check(false))));
  }
}catch{console.error('The license check is unavailable. Check configuration or contact the software developer.');process.exitCode=2;}

PHP

php.phpphp
<?php
// Safe SDK error UX. PHP8.2+, official PHP SDK1.0.0 direct source.
// Run: php php.php; KDP_SDK_DIR/KDP_APP_ID/KDP_STATE_DIR and optional KDP_BASE_URL.
// --self-test reads synthetic cases from stdin; actual result model, no network.
// Output safe message/action/request_id only; never payload/key/token.
declare(strict_types=1);
try {
    $sdk=rtrim((string)getenv('KDP_SDK_DIR'),'/');
    require $sdk.'/src/LicenseResult.php';require $sdk.'/src/LicenseClient.php';
    $policy=json_decode((string)file_get_contents(__DIR__.'/policy.json'),true,64,JSON_THROW_ON_ERROR);
    function explain(KDPika\LicenseSdk\LicenseResult $result,array $policy):array {
        $entry=$result->valid?['message'=>'Your license is ready.','action'=>'continue']:($policy['codes'][$result->errorCode??'']??$policy['fallback']);
        $id=$result->requestId!==null&&preg_match('/^req_[a-f0-9]{24}$/D',$result->requestId)?$result->requestId:null;
        return ['valid'=>$result->valid,'message'=>$entry['message'],'action'=>$entry['action'],'request_id'=>$id];
    }
    if(($argv[1]??'')==='--self-test'&&$argc===2){
        foreach(json_decode((string)stream_get_contents(STDIN),true,64,JSON_THROW_ON_ERROR) as $row){
            $result=new KDPika\LicenseSdk\LicenseResult(valid:$row['valid'],source:'synthetic contract',errorCode:$row['code']??null,requestId:$row['request_id']??null);
            echo json_encode(explain($result,$policy),JSON_THROW_ON_ERROR).PHP_EOL;
        }
    }else{
        if($argc!==1)throw new RuntimeException('Unknown action');
        $client=new KDPika\LicenseSdk\LicenseClient(product:(string)getenv('KDP_APP_ID'),environment:'SANDBOX',baseUrl:getenv('KDP_BASE_URL')?:'https://licensing.kdpika.com',storageDir:(string)getenv('KDP_STATE_DIR'));
        echo json_encode(explain($client->check(false),$policy),JSON_THROW_ON_ERROR).PHP_EOL;
    }
}catch(Throwable){fwrite(STDERR,"The license check is unavailable. Check configuration or contact the software developer.\n");exit(2);}

C#

Program.cscsharp
// Safe SDK error UX. .NET7+, official C# SDK1.0.0 project/package reference.
// Run: dotnet run --project Errors.csproj; KDP_APP_ID/KDP_STATE_DIR, optional site origin KDP_BASE_URL.
// --self-test reads synthetic cases from stdin; actual SDK result model, no network.
// Output safe message/action/request_id only; never raw payload/key/token.
using System.Text.Json;
using System.Text.RegularExpressions;
using KDPika.LicenseSdk;
try
{
    using var policy=JsonDocument.Parse(File.ReadAllText(Path.Combine(AppContext.BaseDirectory,"policy.json")));
    object Explain(LicenseResult result)
    {
        var found=result.ErrorCode is not null&&policy.RootElement.GetProperty("codes").TryGetProperty(result.ErrorCode,out _);
        var entry=found?policy.RootElement.GetProperty("codes").GetProperty(result.ErrorCode!):policy.RootElement.GetProperty("fallback");
        var message=result.Valid?"Your license is ready.":entry.GetProperty("message").GetString();
        var action=result.Valid?"continue":entry.GetProperty("action").GetString();
        var id=result.RequestId is not null&&Regex.IsMatch(result.RequestId,"^req_[a-f0-9]{24}$")?result.RequestId:null;
        return new {valid=result.Valid,message,action,request_id=id};
    }
    if(args.Length==1&&args[0]=="--self-test")
    {
        using var rows=JsonDocument.Parse(Console.In.ReadToEnd());
        foreach(var row in rows.RootElement.EnumerateArray())
        {
            var result=new LicenseResult(row.GetProperty("valid").GetBoolean(),"synthetic contract",default,
                row.TryGetProperty("code",out var code)?code.GetString():null,
                RequestId:row.TryGetProperty("request_id",out var requestId)?requestId.GetString():null);
            Console.WriteLine(JsonSerializer.Serialize(Explain(result)));
        }
    }
    else
    {
        if(args.Length!=0)throw new Exception("Unknown action");
        var client=new LicenseClient(product:Environment.GetEnvironmentVariable("KDP_APP_ID")!,environment:"SANDBOX",
            baseUrl:Environment.GetEnvironmentVariable("KDP_BASE_URL")??"https://licensing.kdpika.com",
            storageDir:Environment.GetEnvironmentVariable("KDP_STATE_DIR"));
        Console.WriteLine(JsonSerializer.Serialize(Explain(await client.CheckAsync(false))));
    }
    return 0;
}
catch(Exception)
{
    Console.Error.WriteLine("The license check is unavailable. Check configuration or contact the software developer.");return 2;
}
Errors.csprojxml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType><TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="../../../../sdk/csharp/KDPika.LicenseSdk/KDPika.LicenseSdk.csproj" />
    <None Include="policy.json" CopyToOutputDirectory="PreserveNewest" />
  </ItemGroup>
</Project>

Install official SDK 1.0.0 as in the quickstart. Python requires 3.9+; PHP requires 8.2+ for the actual readonly result class; Node requires 18.20+ for these examples; C# targets .NET 7+. Keep policy.json beside each sample. For C#, the included project references the SDK in this repository; when using a downloaded SDK, set ProjectReference to that extracted SDK project, and keep policy.json copied to output. Run each file with no arguments to check the configured Sandbox installation. Supply KDP_APP_ID, KDP_STATE_DIR and optional KDP_BASE_URL as the site origin, not /api/v1. PHP additionally uses KDP_SDK_DIR. Node resolves the locally installed @kdpika/license-sdk.

Request IDs and support

Record method, path, UTC time, actual HTTP status and current X-Request-ID. If a create replay body has a different request_id, retain both. SDK-local results can have no request ID; do not manufacture one. Send the IDs and a short description to hi@kdpika.com, not raw keys, tokens, customer payloads or unredacted screenshots.

Show a support reference only if it has the expected req_ correlation format. A reference is not authentication or an access grant. The sample does not render raw server error.message into HTML.

Expected result

Your application denies invalid results, shows the next step, and retains safe correlation details without credentials.

Common mistakes

  • Calling a feature helper without checking result.valid/Valid first.
  • Treating SDK-local errors as an HTTP 500 or retrying every failure.
  • Displaying internal exception text or sending private payloads to support.

Security notes

Fail closed on unknown/signature/cache/clock errors. A friendly message must never turn a refusal into success. The policy is client UX, not new server behavior.

Troubleshooting

SymptomCauseAction
No request IDLocal setup/cache/transport pathRecord the app version/time/code; do not invent a server ID
Code not in this tableNew server/client version or unrelated routeFail closed, preserve safe metadata and contact support
Error message changedHuman wording is not a stable machine contractBranch on code and namespace, not English text

Next steps

Review the endpoint reference and signature verification.

Was this page helpful?

Choose an answer

Do not include personal data, license keys or credentials. Retained for up to 30 days. This is not a support inbox.

Search documentation

Arrow keys to move, Enter to open, Escape to close. Search stays in your browser.

Cookie settings