Admin Endpoints¶
All admin endpoints require either adminSecret (super admin) or an apiKey scoped to your products. See API Overview for delivery methods.
Create License¶
Creates a new license and returns the generated license key.
POST /createLicense
Request¶
{
"adminSecret": "your_secret",
"email": "user@example.com",
"productId": "prod_abc123",
"variant": "pro",
"maxMachines": 3,
"maxConcurrent": 1,
"licenseType": "per-machine",
"expiresAt": "2026-01-01T00:00:00Z",
"discountCode": "SALE50",
"purchaseId": "gum_txn_xyz",
"bundleId": "bundle_suite",
"unlockedProducts": ["prod_abc123", "prod_def456"]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
email |
string | Yes | Customer email address |
productId |
string | Yes | Product to license |
variant |
string | No | Variant name (e.g. pro, studio). Defaults to "indie". |
maxMachines |
number | No | Maximum simultaneous activations. Defaults to 2. |
maxConcurrent |
number | No | Max concurrent floating sessions. Floating licenses only. |
licenseType |
string | No | per-machine, floating, or site. Defaults to "per-machine". |
expiresAt |
string | No | ISO 8601 expiry timestamp. Omit for perpetual licenses. |
discountCode |
string | No | Discount code applied at purchase time. |
purchaseId |
string | No | External transaction ID (e.g. Gumroad sale ID). |
bundleId |
string | No | Bundle identifier for group purchases. |
unlockedProducts |
array | No | List of product IDs unlocked by a bundle license. |
Success Response 200¶
Errors¶
| Status | Cause |
|---|---|
400 |
Missing email or productId |
404 |
productId does not belong to your API key scope |
Examples¶
Get License¶
Returns full license details including all machine activations and any recorded violations.
GET /getLicense or POST /getLicense
Request¶
| Parameter | Type | Required | Description |
|---|---|---|---|
licenseKey |
string | Yes | License key to look up |
Success Response 200¶
{
"success": true,
"license": {
"key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"email": "user@example.com",
"productId": "prod_abc123",
"variant": "indie",
"licenseType": "per-machine",
"status": "active",
"maxMachines": 2,
"createdAt": "2024-01-01T00:00:00Z",
"purchasedAt": "2024-01-01T00:00:00Z",
"expiresAt": null
},
"activations": [
{
"fingerprint": "sha256-of-machine-id",
"hostname": "my-workstation",
"firstSeen": "2024-06-01T00:00:00Z",
"lastSeen": "2024-06-15T00:00:00Z",
"tokenExpiry": "2024-07-15T00:00:00Z",
"sessionStarted": null,
"countries": ["US"],
"lastCountry": "US",
"sessionActive": false
}
],
"violations": []
}
Errors¶
| Status | Cause |
|---|---|
400 |
Missing licenseKey |
401 |
Invalid or missing auth credential |
404 |
License not found |
Examples¶
List Licenses¶
Returns a filtered list of licenses. All filter parameters are optional.
GET /listLicenses or POST /listLicenses
Request¶
{
"adminSecret": "your_secret",
"productId": "prod_abc123",
"email": "user@example.com",
"status": "active",
"limit": 50
}
| Parameter | Type | Required | Description |
|---|---|---|---|
productId |
string | No | Filter by product |
email |
string | No | Filter by customer email |
status |
string | No | Filter by status: active, revoked, expired |
limit |
number | No | Maximum results to return. Defaults to 100. |
Success Response 200¶
{
"success": true,
"licenses": [
{
"key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"email": "user@example.com",
"productId": "prod_abc123",
"variant": "indie",
"status": "active",
"maxMachines": 2,
"createdAt": "2024-01-01T00:00:00Z"
}
],
"count": 1
}
Errors¶
| Status | Cause |
|---|---|
400 |
API key user has more than 30 products and no productId filter was provided |
401 |
Invalid or missing auth credential |
Examples¶
Update License¶
Updates mutable fields on an existing license.
POST /updateLicense
Request¶
{
"adminSecret": "your_secret",
"licenseKey": "XXXX-XXXX-XXXX-XXXX",
"variant": "studio",
"licenseType": "per-machine",
"maxMachines": 5,
"maxConcurrent": 3,
"expiresAt": "2027-01-01T00:00:00Z",
"status": "active"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
licenseKey |
string | Yes | License key to update |
variant |
string | No | New variant name |
licenseType |
string | No | New license type: per-machine, floating, or site |
maxMachines |
number | No | New machine activation limit |
maxConcurrent |
number | No | New concurrent session limit (floating licenses) |
expiresAt |
string | No | New expiry timestamp. Pass null to make perpetual. |
status |
string | No | Override status directly: active or revoked |
Success Response 200¶
Errors¶
| Status | Cause |
|---|---|
400 |
Missing licenseKey |
401 |
Invalid or missing auth credential |
404 |
License not found |
Examples¶
Revoke License¶
Marks a license as revoked. Revoked licenses are denied at all client endpoints.
POST /revokeLicense
Request¶
| Parameter | Type | Required | Description |
|---|---|---|---|
licenseKey |
string | Yes | License key to revoke |
reason |
string | No | Reason for revocation: refund, chargeback, or fraud |
Success Response 200¶
Errors¶
| Status | Cause |
|---|---|
400 |
Missing licenseKey |
401 |
Invalid or missing auth credential |
404 |
License not found |
Examples¶
Reinstate License¶
Reinstates a previously revoked license, setting its status back to active.
POST /reinstateLicense
Request¶
| Parameter | Type | Required | Description |
|---|---|---|---|
licenseKey |
string | Yes | License key to reinstate |
Success Response 200¶
Errors¶
| Status | Cause |
|---|---|
400 |
Missing licenseKey |
401 |
Invalid or missing auth credential |
404 |
License not found |
Examples¶
Resolve Violations¶
Marks specific violations as resolved, recalculating the license threat level and status.
POST /resolveLicense
Request¶
{
"adminSecret": "your_secret",
"licenseKey": "XXXX-XXXX-XXXX-XXXX",
"violationIds": ["viol_001", "viol_002"]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
licenseKey |
string | Yes | License key containing the violations |
violationIds |
array | Yes | IDs of violations to mark as resolved |
Success Response 200¶
Errors¶
| Status | Cause |
|---|---|
400 |
Missing licenseKey or violationIds |
401 |
Invalid or missing auth credential |
404 |
License not found |
Examples¶
import requests
resp = requests.post(
"https://us-central1-cg-license-server.cloudfunctions.net/resolveLicense",
json={
"adminSecret": "your_secret",
"licenseKey": "XXXX-XXXX-XXXX-XXXX",
"violationIds": ["viol_001", "viol_002"],
},
)
data = resp.json()
print(f"Threat level now: {data['threatLevel']}")
Reset Activations¶
Removes all machine activations from a license, freeing all slots. Useful for customer support when a user has lost access to their machines.
POST /resetActivations
Request¶
| Parameter | Type | Required | Description |
|---|---|---|---|
licenseKey |
string | Yes | License key to reset |
Success Response 200¶
Errors¶
| Status | Cause |
|---|---|
400 |
Missing licenseKey |
401 |
Invalid or missing auth credential |
404 |
License not found |