License Verification API
Validate a buyer's license (purchase code) directly from your plugin, theme or application. Use it to gate activation, updates or premium features. The endpoint is public and read-only — your product calls it directly, with no API key to embed or leak.
Always send productId
A license belongs to exactly one product. The valid field is returned only when you pass productId and the key matches it. If you omit it, there is no valid field at all — so a genuine key for a different product can never activate yours. Checking if (data.valid) fails safe.
Endpoint
GET https://esdecode.com/api/licenses/verify| Query param | Required | Description |
|---|---|---|
| key | Yes | The buyer's license key. Case-insensitive. |
| productId | Yes* | The product you are licensing. Required to receive a valid verdict. (*Technically optional — but a request without it can never return valid: true, so any activation check must include it.) |
Finding your product ID
Open the item in your seller dashboard and click Edit — the ID is the last part of the edit URL:
https://esdecode.com/dashboard/items/clx0product0id/edit
└──────┬──────┘
your productIdIt is also returned as license.product.idin every response. Hard-code your own product's ID in your integration.
Response
200 for a well-formed request; 400 (missing key), 404 (unknown key) and 429 (rate-limited) otherwise. Inspect the JSON, never the status code alone.
{
"apiVersion": 1,
"found": true,
"active": true,
"valid": true, // present only because productId was sent & matched
"license": {
"key": "A1B2C3D4-E5F6-...",
"type": "REGULAR",
"typeName": "Regular License",
"product": {
"id": "clx0product0id",
"title": "Acme Booking Plugin",
"slug": "acme-booking-plugin",
"version": "2.1.0",
"author": "Northlight Studio"
},
"licensee": "J*** D***",
"purchasedAt": "2026-01-15T10:24:00.000Z"
}
}| Field | Type | Description |
|---|---|---|
| apiVersion | number | Contract version. Pin your integration against this; a bump signals a breaking change. |
| valid | boolean (only if productId sent) | true only when the key is genuine, active AND belongs to the productId you passed. Absent when productId is omitted — see the warning below. |
| found | boolean | Whether the key exists at all. |
| active | boolean | Whether the key is genuine and not revoked/refunded (independent of product match). |
| error | string | Present on a failed or negative check. Human-readable reason. |
| license.key | string | The verified license key, normalised to uppercase. |
| license.type | "REGULAR" | "EXTENDED" | License tier purchased. |
| license.typeName | string | Display name, e.g. "Regular License". |
| license.product.id | string | Marketplace product ID the key belongs to. |
| license.product.title | string | Product title at time of verification. |
| license.product.slug | string | URL slug of the product. |
| license.product.version | string | null | Current published version, if set. |
| license.product.author | string | null | Seller display name. |
| license.licensee | string | Buyer name, masked for privacy (e.g. "J*** D***"). |
| license.purchasedAt | string (ISO 8601) | When the purchase was completed. |
Revocation
A key becomes active: false (and valid: false) the moment its purchase is refunded or a chargeback is opened. Responses are never cached, so verify on activation and periodically (e.g. on update checks) rather than storing a permanent “valid” flag.
Rate limits
Up to 30 requests per minute per IP. Exceeding it returns HTTP 429 with a Retry-After header (seconds). Verify on activation and cache the outcome in your own product for a short period rather than calling on every page load.
Examples
cURL
curl "https://esdecode.com/api/licenses/verify?key=YOUR-LICENSE-KEY&productId=YOUR-PRODUCT-ID"PHP
<?php
$key = trim($_POST['purchase_code'] ?? '');
$myItemId = 'YOUR-PRODUCT-ID'; // your product's ID (see "Finding your product ID")
$url = 'https://esdecode.com/api/licenses/verify?' . http_build_query([
'key' => $key,
'productId' => $myItemId, // REQUIRED — without it, valid is never true
]);
$res = json_decode(file_get_contents($url), true);
if (!empty($res['valid'])) {
// genuine, active, and issued for THIS product → activate
} else {
// invalid, revoked, refunded, or for a different item → reject
}JavaScript
const key = purchaseCode.trim();
const myItemId = "YOUR-PRODUCT-ID"; // required
const res = await fetch(
`https://esdecode.com/api/licenses/verify?key=${encodeURIComponent(key)}&productId=${myItemId}`
);
const data = await res.json();
if (data.valid) {
// activate
} else {
// reject
}Need to check a single key by hand? Use the license verification page. Questions about integrating this in your product? Contact us.