Licenses
The Licenses API endpoints helps you manage licenses purchased through your store.
License instances are part of a license key. Each license key can be linked to multiple instances. Whenever you activate a license key, you create a new instance of the license key.
The license key model
The license key model represents a single license key purchased by a customer.
Properties
- Name
id
- Type
- integer
- Description
(read-only) The unique identifier for the license key.
- Name
key
- Type
- string
- Description
(read-only) The actual license key string
- Name
limit
- Type
- integer | null
- Description
The maximum number of instances this key can be activated on.
null
means unlimited activations.
- Name
active
- Type
- boolean
- Description
Whether the license key is currently active which you can modify via the API and which is unrelated to the status. Inactive keys cannot be activated or validated successfully.
- Name
status
- Type
- string
- Description
(read-only) The status of the license key, one of:
ACTIVE
,INACTIVE
,EXPIRED
- Name
expires_at
- Type
- timestamp | null
- Description
The timestamp when the license key expires.
null
means the license will never expire.
- Name
is_expired
- Type
- boolean
- Description
Whether the license key is expired.
- Name
store_id
- Type
- integer
- Description
(read-only) The ID of the store this license key belongs to.
- Name
order_id
- Type
- integer | null
- Description
(read-only) The ID of the order associated with this license key.
- Name
invoice_id
- Type
- integer | null
- Description
(read-only) The ID of the associated invoice V2, if applicable.
- Name
product_id
- Type
- integer
- Description
(read-only) The ID of the product this license is for.
- Name
variant_id
- Type
- integer
- Description
(read-only) The ID of the specific product variant this license is for.
- Name
customer_id
- Type
- integer
- Description
(read-only) The ID of the customer that purchased this license key.
- Name
subscription_id
- Type
- integer | null
- Description
(read-only) The ID of the associated subscription, if applicable.
- Name
created_at
- Type
- timestamp
- Description
(read-only) Time at which the license key was created.
- Name
updated_at
- Type
- timestamp
- Description
(read-only) Time at which the license key was last updated.
The license instance model
The license instance model represents a single activation of a license key on a specific device or identifier.
Properties
- Name
id
- Type
- string (uuid)
- Description
(read-only) The unique identifier (UUID) of the license instance. This is the
instance_id
used for validation.
- Name
license_key_id
- Type
- integer
- Description
(read-only) The unique identifier for the parent license key which this instance is linked to.
- Name
name
- Type
- string
- Description
(read-only) The name provided during activation, which you can use to identify this instance (e.g., the customer's email or HWID).
- Name
store_id
- Type
- integer
- Description
(read-only) The ID of the store this instance belongs to.
- Name
created_at
- Type
- timestamp
- Description
(read-only) Time at which the instance was created (activation time).
- Name
updated_at
- Type
- timestamp
- Description
(read-only) Time at which the instance was last updated.
Activate a license key
This endpoint activates a given license key and creates an instance of the license key. Activation registers a unique identifier (instance name) against the license key. If the activation is successful, it returns the details of the newly created LicenseKeyInstance
, including its unique id
which should be stored by the client/application for future validation.
Activation can fail if:
- The license key does not exist.
- The license key is inactive (
active
is false). - The license key has expired (
expires_at
is in the past). - The activation limit (
limit
) has been reached.
Required attributes
- Name
license_key
- Type
- string
- Description
The license key string to activate.
- Name
instance_name
- Type
- string
- Description
A unique name or identifier for this instance (e.g., user email, HWID, server hostname). This name helps you identify this instance.
Request
$request = new HttpRequest();
$request->setUrl('https://sell.app/api/v2/licenses/activate');
$request->setMethod(HTTP_METH_POST);
$request->setHeaders([
'Content-Type' => 'application/json',
'accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN'
]);
$request->setBody(json_encode([
'license_key' => '01965f1d-f038-7116-b57f-9e7ecb4e7b8f',
'instance_name' => 'zezima@osrs.com'
]));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Response (Success 200)
{
"name": "zezima@osrs.com",
"store_id": 1,
"license_key_id": 1,
"id": "9ebd2de0-61fb-4966-a319-2a75b27f5ddf", // Instance ID to store
"updated_at": "2025-04-22T20:08:39.000000Z",
"created_at": "2025-04-22T20:08:39.000000Z"
}
Response (Error 422)
{
"message": "This license key has reached its activation limit.",
"license_key": {
"id": 1,
"status": "ACTIVE", // Current status
"expired_at": "2025-01-01T00:00:00.000000Z" // Expiration date
}
}
On successful activation, store the returned instance id
. You'll need it for validation.
Validate a license key
Checks if a given license key and instance ID pair represents a valid, active license activation. This is the primary endpoint to use within your application to verify a user's license status periodically.
Validation checks if:
- The license key exists.
- The license key is currently
active
. - The license key has not expired (
expires_at
). - The provided
instance_id
matches an existing activation for that license key.
Required attributes
- Name
license_key
- Type
- string
- Description
The license key string to validate.
- Name
instance_id
- Type
- string
- Description
The unique ID of the instance that was returned upon successful activation.
Request
$request = new HttpRequest();
$request->setUrl('https://sell.app/api/v2/licenses/validate');
$request->setMethod(HTTP_METH_POST);
$request->setHeaders([
'Content-Type' => 'application/json',
'accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN'
]);
$request->setBody(json_encode([
'license_key' => '01965f1d-f038-7116-b57f-9e7ecb4e7b8f',
'instance_id' => '9ebd3be0-de72-4da7-805e-bc99d1ac1186'
]));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Response (Success 200)
{
"valid": true,
"license_key": {
"id": 1,
"key": "01965f1d-f038-7116-b57f-9e7ecb4e7b8f",
"limit": 4,
"active": 1,
"status": "ACTIVE",
"expires_at": "2025-05-22T20:08:39.000000Z",
"is_expired": 0,
"store_id": 1,
"order_id": 1,
"invoice_id": 1,
"product_id": 218,
"variant_id": 228,
"customer_id": 1,
"subscription_id": null,
"created_at": "2025-04-22T20:08:39.000000Z",
"updated_at": "2025-04-22T20:08:39.000000Z",
"instances_count": 4
},
"instance": {
"id": "9ebd3be0-de72-4da7-805e-bc99d1ac1186",
"license_key_id": 1,
"name": "zezima@osrs.com",
"store_id": 1,
"created_at": "2025-04-22T21:05:06.000000Z",
"updated_at": "2025-04-22T21:05:06.000000Z"
}
}
Response (Invalid 422)
{
"message": "License key not found"
}
The primary check should be the valid
boolean field in the response. If true
, the application can proceed. If false
, access should be restricted. The license_key
and instance
objects provide additional context.
List all license keys
Retrieves a paginated list of all license keys associated with your store. Standard pagination parameters (limit
, page
) can be used.
Refer to the license key model section for details on the returned object structure.
Optional Query Parameters
- Name
limit
- Type
- integer
- Description
Limit the number of license keys returned per page.
- Name
page
- Type
- integer
- Description
The page number to retrieve.
Request
$request = new HttpRequest();
$request->setUrl('https://sell.app/api/v2/license-keys'); // Add ?limit=10&page=2 for pagination
$request->setMethod(HTTP_METH_GET);
$request->setHeaders([
'accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN'
]);
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Response
{
"data": [
{
"id": 1,
"key": "01965f1d-f038-7116-b57f-9e7ecb4e7b8f",
"limit": 4,
"active": 1,
"status": "ACTIVE",
"expires_at": "2025-05-22T20:08:39.000000Z",
"is_expired": 0,
"store_id": 1,
"order_id": 1,
"invoice_id": 1,
"product_id": 1,
"variant_id": 1,
"customer_id": 1,
"subscription_id": null,
"created_at": "2025-04-22T20:08:39.000000Z",
"updated_at": "2025-04-22T20:08:39.000000Z"
}
]
}
Retrieve a license key
Retrieves the details of a specific license key by its unique ID (not key!)
Refer to the license key model section for details on the returned object structure.
Required attributes
- Name
id
- Type
- integer
- Description
The ID of the license key to retrieve.
Request
$request = new HttpRequest();
$request->setUrl('https://sell.app/api/v2/license-keys/1');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders([
'accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN'
]);
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Response
{
"data": {
"id": 1,
"key": "01965f1d-f038-7116-b57f-9e7ecb4e7b8f",
"limit": 4,
"active": 1,
"status": "ACTIVE",
"expires_at": "2025-05-22T20:08:39.000000Z",
"is_expired": 0,
"store_id": 1,
"order_id": 1,
"invoice_id": 1,
"product_id": 1,
"variant_id": 1,
"customer_id": 1,
"subscription_id": null,
"created_at": "2025-04-22T20:08:39.000000Z",
"updated_at": "2025-04-22T20:08:39.000000Z"
}
}
Update a license key
Updates specific properties of a license key. You can modify the activation limit, expiration date, and active status.
If you decrease the limit
to a value lower than the current instances_count
, the oldest instances will be automatically deleted to match the new limit.
Required attributes
- Name
id
- Type
- integer
- Description
The ID of the license key to update.
Optional attributes
- Name
limit
- Type
- integer | null
- Description
New activation limit (minimum 1). Set to
null
for unlimited.
- Name
expires_at
- Type
- timestamp | null
- Description
New expiration date (must be in the future). Set to
null
for no expiration. Format:YYYY-MM-DD HH:MM:SS
.
- Name
active
- Type
- boolean
- Description
Set to
true
to activate orfalse
to deactivate the license key and its instances.
Request
$request = new HttpRequest();
$request->setUrl('https://sell.app/api/v2/license-keys/1');
$request->setMethod(HTTP_METH_PATCH); // Use PATCH
$request->setHeaders([
'Content-Type' => 'application/json',
'accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN'
]);
$request->setBody(json_encode([
'limit' => 10,
'expires_at' => '2025-05-03 20:00:00',
'active' => false
]));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Response
{
"data": {
"id": 1,
"key": "01965f1d-f038-7116-b57f-9e7ecb4e7b8f",
"limit": 10,
"active": 0,
"status": "ACTIVE",
"expires_at": "2025-05-03T20:00:00.000000Z",
"is_expired": 0,
"store_id": 1,
"order_id": 1,
"invoice_id": 1,
"product_id": 1,
"variant_id": 1,
"customer_id": 1,
"subscription_id": null,
"created_at": "2025-04-22T20:08:39.000000Z",
"updated_at": "2025-04-22T21:20:51.000000Z",
"instances_count": 4
}
}