API reference
Public and dashboard APIs.
Use an API key from the client dashboard for player activation. Dashboard session routes manage products, keys, licenses, and protection jobs after Discord sign-in.
Public: activate a player license
POST /api/v1/licenses/activate
Authorization: Bearer <api-key>
{ "licenseKey": string, "hwid": string }
-> 200 { key, status, hwidBound, activatedAt, productId }
-> 409 { error: "license_not_found" | "license_inactive" | "license_expired" | "hwid_mismatch" | "product_mismatch" }
-> 401 { error: "unauthorized" }
-> 400 { error: "licenseKey_and_hwid_required" }Rate-limit this on your side as well. API keys are scoped to one of your products.
Dashboard session: customer workspace
These require a signed-in Discord browser session (same-origin cookies), not an API key.
GET /api/customer/products
POST /api/customer/products { name, summary? }
GET /api/customer/api-keys
POST /api/customer/api-keys { productId, label? }
POST /api/customer/api-keys/:id/revoke
GET /api/customer/licenses
POST /api/customer/licenses { productId, note?, expiresInDays? }
POST /api/customer/licenses/:id/revoke
POST /api/customer/licenses/:id/reset-hwidDashboard session: protection jobs
POST /api/jobs multipart: file=.jar, productId?
GET /api/jobs/:id
GET /api/jobs/:id/output protected jar when status=completeJobs always run the client protection profile with native bridge enabled. Uploaded jars are never executed as programs — they are input data only.
Legacy public activate
POST /api/license/activate still exists for older Phantom-owned entitlement flows. New client integrations should use /api/v1/licenses/activate with a product API key.