Guide
Licensing Overview
How SoundSync plugin licensing moves from product credentials to activation, local state, validation, offline grace, and deactivation.
SoundSync
Core plugin endpoints
Product connection, claims, activation, validation, and deactivation have distinct authentication and access effects.
/api/plugin-connections/verify
Verify the standard product credential tuple or supported native public-client app/product identity before customer activation testing.
- Auth
- JSON body credential check. Headers are not used for this endpoint.
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- productId: integer (required)
- appId: string (required)
- pluginKey: string
- pluginSecret: string
- publicClient: hise-native | juce-native
- pluginVersion: string
- environment: string
- Returns
- ok/connected, productId, credentialId, pluginVersion, environment, lastSeenAt.
- Side effects
- Updates credential last-used state, upserts plugin connection status, and records a plugin connection event.
- Notes
- This endpoint reads its JSON body rather than substituting licensing headers. The native public-client path does not require a distributed pluginSecret. Connectivity/product identification is not customer entitlement or audio unlock.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"productId": {
"type": "integer",
"minimum": 1
},
"appId": {
"type": "string"
},
"pluginKey": {
"type": "string"
},
"pluginSecret": {
"type": "string"
},
"publicClient": {
"enum": [
"hise-native",
"juce-native"
]
},
"pluginVersion": {
"type": "string"
},
"environment": {
"type": "string"
}
},
"required": [
"productId",
"appId"
],
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"message": {
"type": "string"
}
},
"additionalProperties": true
}
/api/license/v1/claim
Start a serial claim when customer identity or email verification is required.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- instance_id: string
- machine_id: string
- product_id: integer
- plugin_version: string
- version: string
- license_key: string (required)
- email: string (required)
- Returns
- pending_email_verification with claim_id/claimId and emailSent when verification is required.
- Side effects
- Creates or restores a pending serial claim and can send the verification email.
- Notes
- Requires a serial/license_key, customer email and instance_id (machine_id is an alias). A pending response includes claim_id and emailSent:true; it does not activate the device. 503 VERIFICATION_EMAIL_FAILED with emailSent:false is not confirmed delivery or authorization: retry the claim deliberately after recovery. Owner mismatch/login-required errors do not transfer ownership. Keep the same serial and machine through claim-status and final activation. A compatibility CUSTOMER_ACCOUNT_EXISTS response directs account login/password recovery, not offline access.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"instance_id": {
"type": "string"
},
"machine_id": {
"type": "string"
},
"product_id": {
"type": "integer",
"minimum": 1
},
"plugin_version": {
"type": "string"
},
"version": {
"type": "string"
},
"license_key": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
}
},
"required": [
"license_key",
"email"
],
"additionalProperties": true,
"anyOf": [
{
"required": [
"instance_id"
]
},
{
"required": [
"machine_id"
]
}
]
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"claim_id": {
"type": "string"
},
"claimId": {
"type": "string"
},
"emailSent": {
"type": "boolean"
},
"message": {
"type": "string"
},
"nextAction": {
"type": "string"
},
"passwordResetUrl": {
"type": "string"
},
"claimRequired": {
"type": "boolean"
},
"ownerVerificationRequired": {
"type": "boolean"
},
"requiredFields": {
"type": "array",
"items": {
"type": "string"
}
},
"claim_activation_token": {
"type": "string"
},
"claimActivationToken": {
"type": "string"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 429, 500, 503.
Operation errors: IDENTITY_FIELDS_REQUIRED, INVALID_EMAIL, SERIAL_OWNER_EMAIL_MISMATCH, SERIAL_OWNER_LOGIN_REQUIRED, VERIFICATION_EMAIL_FAILED.
/api/license/v1/claim-status
Restore a pending serial claim and receive claim activation material after email verification.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- query license_key: string (required)
- query instance_id: string (required)
- query claim_id: string
- Returns
- pending_email_verification, verified with claim_activation_token/claimActivationToken, or identity_required. Inspect status/code and ok; HTTP 200 alone is not activation.
- Side effects
- Does not activate the machine. The client must call /activate after verified status.
- Notes
- HTTP 200 may mean pending_email_verification, verified or identity_required; inspect status/code and ok. Only verified returns claim_activation_token for a separate final POST /activate on the same product/serial/machine. 400 VERIFICATION_RESTART_REQUIRED means the link expired or was not sent: submit email and serial to /claim again instead of polling forever. A confirmed owner/access denial is not offline grace. Pending polling/finalization can retry transient outages without discarding the saved claim. GET is a compatibility transport; prefer POST to keep serial/proof out of URLs and logs.
Request, response and error reference
Query and header parameters
[
{
"name": "license_key",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "instance_id",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "claim_id",
"in": "query",
"required": false,
"schema": {
"type": "string"
}
}
]
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"claim_id": {
"type": "string"
},
"claimId": {
"type": "string"
},
"emailSent": {
"type": "boolean"
},
"message": {
"type": "string"
},
"nextAction": {
"type": "string"
},
"passwordResetUrl": {
"type": "string"
},
"claimRequired": {
"type": "boolean"
},
"ownerVerificationRequired": {
"type": "boolean"
},
"requiredFields": {
"type": "array",
"items": {
"type": "string"
}
},
"claim_activation_token": {
"type": "string"
},
"claimActivationToken": {
"type": "string"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 429, 500, 503.
Operation errors: VERIFICATION_RESTART_REQUIRED.
/api/license/v1/claim-status
Restore a pending serial claim and receive claim activation material after email verification.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- instance_id: string (required)
- machine_id: string
- product_id: integer
- plugin_version: string
- version: string
- license_key: string (required)
- claim_id: string
- Returns
- pending_email_verification, verified with claim_activation_token/claimActivationToken, or identity_required. Inspect status/code and ok; HTTP 200 alone is not activation.
- Side effects
- Does not activate the machine. The client must call /activate after verified status.
- Notes
- HTTP 200 may mean pending_email_verification, verified or identity_required; inspect status/code and ok. Only verified returns claim_activation_token for a separate final POST /activate on the same product/serial/machine. 400 VERIFICATION_RESTART_REQUIRED means the link expired or was not sent: submit email and serial to /claim again instead of polling forever. A confirmed owner/access denial is not offline grace. Pending polling/finalization can retry transient outages without discarding the saved claim. GET is a compatibility transport; prefer POST to keep serial/proof out of URLs and logs.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"instance_id": {
"type": "string"
},
"machine_id": {
"type": "string"
},
"product_id": {
"type": "integer",
"minimum": 1
},
"plugin_version": {
"type": "string"
},
"version": {
"type": "string"
},
"license_key": {
"type": "string"
},
"claim_id": {
"type": "string"
}
},
"required": [
"license_key",
"instance_id"
],
"additionalProperties": true
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"claim_id": {
"type": "string"
},
"claimId": {
"type": "string"
},
"emailSent": {
"type": "boolean"
},
"message": {
"type": "string"
},
"nextAction": {
"type": "string"
},
"passwordResetUrl": {
"type": "string"
},
"claimRequired": {
"type": "boolean"
},
"ownerVerificationRequired": {
"type": "boolean"
},
"requiredFields": {
"type": "array",
"items": {
"type": "string"
}
},
"claim_activation_token": {
"type": "string"
},
"claimActivationToken": {
"type": "string"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 429, 500, 503.
Operation errors: VERIFICATION_RESTART_REQUIRED.
/api/license/v1/activate
Activate the current machine after direct serial/customer proof or a verified serial claim.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- instance_id: string
- machine_id: string
- product_id: integer
- plugin_version: string
- version: string
- license_key: string
- serial: string
- email: string
- validation_token: string
- token: string
- activationId: value
- licenseReference: string
- plugin_session_id: string
- device_credential: string. Private renewal proof returned by authorized enrollment; deviceCredential is an accepted body alias. Bind to the same app/product and instance_id. It cannot independently unlock offline audio.
- license_kind: serial | email_entitlement
- device_credential_supported: boolean. Send true to request native renewal-credential enrollment. deviceCredentialSupported is an accepted body alias.
- claim_id: string
- claim_activation_token: string
- Returns
- status activated, activationId, validation_token, entitlement_id, customer, max_activations, remaining, productId, grace_expires_at, offline_grace_days.
- Side effects
- Creates or reactivates a machine activation, ensures entitlement state, marks serial redeemed/billing eligible where applicable, records events, and issues a validation token.
- Notes
- Generated native clients request device_credential_supported:true and retain the returned device_credential, plugin_session_id and newest validation_token privately. Device proof can renew after a short-lived token/session expires, but never bypasses revoked access, product/device binding or entitlement checks. device_credential_status:pending is incomplete enrollment, not an offline grant. Only an authorized signed offline_lease can support JUCE offline access.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"instance_id": {
"type": "string"
},
"machine_id": {
"type": "string"
},
"product_id": {
"type": "integer",
"minimum": 1
},
"plugin_version": {
"type": "string"
},
"version": {
"type": "string"
},
"license_key": {
"type": "string"
},
"serial": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"validation_token": {
"type": "string"
},
"token": {
"type": "string"
},
"activationId": {
"oneOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "string",
"pattern": "^[1-9][0-9]*$"
}
]
},
"licenseReference": {
"type": "string"
},
"plugin_session_id": {
"type": "string"
},
"device_credential": {
"type": "string",
"description": "Private renewal proof returned by authorized enrollment; deviceCredential is an accepted body alias. Bind to the same app/product and instance_id. It cannot independently unlock offline audio."
},
"license_kind": {
"type": "string",
"enum": [
"serial",
"email_entitlement"
]
},
"device_credential_supported": {
"type": "boolean",
"description": "Send true to request native renewal-credential enrollment. deviceCredentialSupported is an accepted body alias."
},
"claim_id": {
"type": "string"
},
"claim_activation_token": {
"type": "string"
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"instance_id"
]
},
{
"required": [
"machine_id"
]
}
]
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"activationId": {
"type": "integer",
"minimum": 1
},
"validation_token": {
"type": "string"
},
"entitlement_id": {
"type": "integer",
"minimum": 1
},
"customer": {
"type": "object",
"properties": {},
"additionalProperties": true
},
"productId": {
"type": "integer",
"minimum": 1
},
"device_credential": {
"type": "string",
"description": "Private product/device-bound renewal proof. Returned when device_credential_supported is true and enrollment succeeds. Protect it in native secure storage; it is not a portal/library token or an offline grant."
},
"device_credential_status": {
"type": "string",
"enum": [
"ready",
"pending"
],
"description": "pending means renewal enrollment is incomplete, even when activation was otherwise authorized. Follow the maintained client retry and access decision; do not manufacture offline authorization."
},
"plugin_session_id": {
"type": "string",
"description": "Private short-lived plugin license session. Distinct from durable device_credential and customer library tokens."
},
"plugin_session_expires_at": {
"type": "string",
"format": "date-time",
"description": "Expiry of plugin_session_id, not the offline grace deadline."
},
"max_activations": {
"type": "integer",
"minimum": 0
},
"remaining": {
"type": "integer",
"minimum": 0
},
"grace_expires_at": {
"type": [
"string",
"null"
]
},
"offline_grace_days": {
"type": "integer",
"minimum": 0
},
"offline_grace": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"days": {
"type": "integer",
"minimum": 0
},
"expiresAt": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": true
},
"offline_lease": {
"type": "string",
"description": "Optional signed JSON envelope issued only by successful authorized activation/validation with a positive grace period and configured signer. Contains alg, kid, base64 payload and signature. Verify with trusted package public keys; decoding alone is not authorization. Never log customer grants."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 500, 503.
/api/license/v1/customer-login/activate
Activate by customer account identity when the product supports account/login activation.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- instance_id: string
- machine_id: string
- product_id: integer
- plugin_version: string
- version: string
- device_credential_supported: boolean. Send true to request native renewal-credential enrollment. deviceCredentialSupported is an accepted body alias.
- email: string
- password: string
- customer_token: string
- Returns
- activation result with validation token, entitlement/customer details, device limit and subscription state where applicable.
- Notes
- The token branch resolves the verified customer identity from the token. Never persist account passwords or substitute a developer token; product ownership and device checks still apply. The direct email/password compatibility branch cannot complete a two-factor challenge: it returns 401 TWO_FACTOR_REQUIRED for an enabled account. Current JUCE 0.7.3 and HISE Native 0.5.2 clients first call /api/auth/login with role:customer, continue with twoFactorToken/twoFactorCode when requested, then pass the verified customer token as customer_token here. Never substitute the challenge token or a developer session. Entitlement and machine checks still apply. Regenerate and rebuild older packages; see the dedicated customer-login guide for the complete conversation. When account-token session verification is unavailable, fail closed with 503 SESSION_VERIFICATION_UNAVAILABLE. Retry after recovery; do not treat it as authorization or confirmed revocation. A verified revoked account session returns 401 LIBRARY_SESSION_REVOKED. Shared library tokens follow their own token/ownership checks.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"instance_id": {
"type": "string"
},
"machine_id": {
"type": "string"
},
"product_id": {
"type": "integer",
"minimum": 1
},
"plugin_version": {
"type": "string"
},
"version": {
"type": "string"
},
"device_credential_supported": {
"type": "boolean",
"description": "Send true to request native renewal-credential enrollment. deviceCredentialSupported is an accepted body alias."
},
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string"
},
"customer_token": {
"type": "string",
"minLength": 1
}
},
"additionalProperties": true,
"allOf": [
{
"anyOf": [
{
"required": [
"instance_id"
]
},
{
"required": [
"machine_id"
]
}
]
},
{
"anyOf": [
{
"required": [
"email",
"password"
]
},
{
"required": [
"customer_token"
]
}
]
}
]
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"activationId": {
"type": "integer",
"minimum": 1
},
"validation_token": {
"type": "string"
},
"entitlement_id": {
"type": "integer",
"minimum": 1
},
"customer": {
"type": "object",
"properties": {},
"additionalProperties": true
},
"productId": {
"type": "integer",
"minimum": 1
},
"device_credential": {
"type": "string",
"description": "Private product/device-bound renewal proof. Returned when device_credential_supported is true and enrollment succeeds. Protect it in native secure storage; it is not a portal/library token or an offline grant."
},
"device_credential_status": {
"type": "string",
"enum": [
"ready",
"pending"
],
"description": "pending means renewal enrollment is incomplete, even when activation was otherwise authorized. Follow the maintained client retry and access decision; do not manufacture offline authorization."
},
"plugin_session_id": {
"type": "string",
"description": "Private short-lived plugin license session. Distinct from durable device_credential and customer library tokens."
},
"plugin_session_expires_at": {
"type": "string",
"format": "date-time",
"description": "Expiry of plugin_session_id, not the offline grace deadline."
},
"max_activations": {
"type": "integer",
"minimum": 0
},
"remaining": {
"type": "integer",
"minimum": 0
},
"grace_expires_at": {
"type": [
"string",
"null"
]
},
"offline_grace_days": {
"type": "integer",
"minimum": 0
},
"offline_grace": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"days": {
"type": "integer",
"minimum": 0
},
"expiresAt": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": true
},
"offline_lease": {
"type": "string",
"description": "Optional signed JSON envelope issued only by successful authorized activation/validation with a positive grace period and configured signer. Contains alg, kid, base64 payload and signature. Verify with trusted package public keys; decoding alone is not authorization. Never log customer grants."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 500, 503.
Operation errors: CUSTOMER_LOGIN_INVALID, TWO_FACTOR_REQUIRED, EMAIL_VERIFICATION_REQUIRED, SESSION_VERIFICATION_UNAVAILABLE, LIBRARY_SESSION_REVOKED.
/api/license/v1/validate
Validate cached activation state on startup or during periodic revalidation.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- instance_id: string
- machine_id: string
- product_id: integer
- plugin_version: string
- version: string
- license_key: string
- serial: string
- email: string
- validation_token: string
- token: string
- activationId: value
- licenseReference: string
- plugin_session_id: string
- device_credential: string. Private renewal proof returned by authorized enrollment; deviceCredential is an accepted body alias. Bind to the same app/product and instance_id. It cannot independently unlock offline audio.
- license_kind: serial | email_entitlement
- device_credential_supported: boolean. Send true to request native renewal-credential enrollment. deviceCredentialSupported is an accepted body alias.
- claim_id: string
- claim_activation_token: string
- Returns
- active/denied state, rotated validation token, last validation timestamps, offline grace fields, subscription/license state.
- Side effects
- Refreshes validation state and token when allowed. Explicit denials force lock and must not use offline grace.
- Notes
- Generated native clients request device_credential_supported:true and retain the returned device_credential, plugin_session_id and newest validation_token privately. Device proof can renew after a short-lived token/session expires, but never bypasses revoked access, product/device binding or entitlement checks. device_credential_status:pending is incomplete enrollment, not an offline grant. Only an authorized signed offline_lease can support JUCE offline access.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"instance_id": {
"type": "string"
},
"machine_id": {
"type": "string"
},
"product_id": {
"type": "integer",
"minimum": 1
},
"plugin_version": {
"type": "string"
},
"version": {
"type": "string"
},
"license_key": {
"type": "string"
},
"serial": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"validation_token": {
"type": "string"
},
"token": {
"type": "string"
},
"activationId": {
"oneOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "string",
"pattern": "^[1-9][0-9]*$"
}
]
},
"licenseReference": {
"type": "string"
},
"plugin_session_id": {
"type": "string"
},
"device_credential": {
"type": "string",
"description": "Private renewal proof returned by authorized enrollment; deviceCredential is an accepted body alias. Bind to the same app/product and instance_id. It cannot independently unlock offline audio."
},
"license_kind": {
"type": "string",
"enum": [
"serial",
"email_entitlement"
]
},
"device_credential_supported": {
"type": "boolean",
"description": "Send true to request native renewal-credential enrollment. deviceCredentialSupported is an accepted body alias."
},
"claim_id": {
"type": "string"
},
"claim_activation_token": {
"type": "string"
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"instance_id"
]
},
{
"required": [
"machine_id"
]
}
]
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"activationId": {
"type": "integer",
"minimum": 1
},
"validation_token": {
"type": "string"
},
"entitlement_id": {
"type": "integer",
"minimum": 1
},
"customer": {
"type": "object",
"properties": {},
"additionalProperties": true
},
"productId": {
"type": "integer",
"minimum": 1
},
"device_credential": {
"type": "string",
"description": "Private product/device-bound renewal proof. Returned when device_credential_supported is true and enrollment succeeds. Protect it in native secure storage; it is not a portal/library token or an offline grant."
},
"device_credential_status": {
"type": "string",
"enum": [
"ready",
"pending"
],
"description": "pending means renewal enrollment is incomplete, even when activation was otherwise authorized. Follow the maintained client retry and access decision; do not manufacture offline authorization."
},
"plugin_session_id": {
"type": "string",
"description": "Private short-lived plugin license session. Distinct from durable device_credential and customer library tokens."
},
"plugin_session_expires_at": {
"type": "string",
"format": "date-time",
"description": "Expiry of plugin_session_id, not the offline grace deadline."
},
"max_activations": {
"type": "integer",
"minimum": 0
},
"remaining": {
"type": "integer",
"minimum": 0
},
"grace_expires_at": {
"type": [
"string",
"null"
]
},
"offline_grace_days": {
"type": "integer",
"minimum": 0
},
"offline_grace": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"days": {
"type": "integer",
"minimum": 0
},
"expiresAt": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": true
},
"offline_lease": {
"type": "string",
"description": "Optional signed JSON envelope issued only by successful authorized activation/validation with a positive grace period and configured signer. Contains alg, kid, base64 payload and signature. Verify with trusted package public keys; decoding alone is not authorization. Never log customer grants."
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 500, 503.
/api/license/v1/deactivate
Deactivate this machine and release local access.
- Auth
- x-ss-app-id + x-ss-plugin-key + x-ss-plugin-secret OR x-ss-app-id + x-ss-product-id + x-soundsync-public-client (matching generated native client)
- Scope
- Product, app, credential, environment, and machine scoped.
- Request fields
- instance_id: string
- machine_id: string
- product_id: integer
- plugin_version: string
- version: string
- license_key: string
- serial: string
- email: string
- validation_token: string
- token: string
- activationId: value
- licenseReference: string
- plugin_session_id: string
- device_credential: string. Private renewal proof returned by authorized enrollment; deviceCredential is an accepted body alias. Bind to the same app/product and instance_id. It cannot independently unlock offline audio.
- license_kind: serial | email_entitlement
- claim_id: string
- claim_activation_token: string
- deviceCredential: string
- pluginSessionId: string
- session_id: string
- sessionId: string
- soundSyncSessionId: string
- soundsync_session_id: string
- validationToken: string
- new_token: string
- newToken: string
- Returns
- status deactivated, code DEVICE_DEACTIVATED, remaining_activations.
- Side effects
- Sets deactivated_at on the activation, records an event, and should cause the client to delete local activation state.
- Notes
- Send the retained device_credential or permitted plugin_session_id with the same product and machine identity. A supported validation-token proof is a separate compatibility path: send the current validation_token with its serial/email or activation context. Product credential headers, a serial and a machine ID alone are not deactivation proof. Missing or invalid compatibility proof returns 401 deactivate_validation_token_required or deactivate_validation_token_invalid. A nonempty proof field only satisfies the request shape; the server still verifies signature, ownership, product, machine and activation generation. Confirm status/code and deactivation flags before claiming server slot release. JUCE locks locally and preserves pending proof until confirmed; deactivation does not issue a fresh offline grant.
Request, response and error reference
Request (application/json)
{
"type": "object",
"properties": {
"instance_id": {
"type": "string"
},
"machine_id": {
"type": "string"
},
"product_id": {
"type": "integer",
"minimum": 1
},
"plugin_version": {
"type": "string"
},
"version": {
"type": "string"
},
"license_key": {
"type": "string"
},
"serial": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"validation_token": {
"type": "string",
"minLength": 1
},
"token": {
"type": "string",
"minLength": 1
},
"activationId": {
"oneOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "string",
"pattern": "^[1-9][0-9]*$"
}
]
},
"licenseReference": {
"type": "string"
},
"plugin_session_id": {
"type": "string",
"minLength": 1
},
"device_credential": {
"type": "string",
"description": "Private renewal proof returned by authorized enrollment; deviceCredential is an accepted body alias. Bind to the same app/product and instance_id. It cannot independently unlock offline audio.",
"minLength": 1
},
"license_kind": {
"type": "string",
"enum": [
"serial",
"email_entitlement"
]
},
"claim_id": {
"type": "string"
},
"claim_activation_token": {
"type": "string"
},
"deviceCredential": {
"type": "string",
"minLength": 1
},
"pluginSessionId": {
"type": "string",
"minLength": 1
},
"session_id": {
"type": "string",
"minLength": 1
},
"sessionId": {
"type": "string",
"minLength": 1
},
"soundSyncSessionId": {
"type": "string",
"minLength": 1
},
"soundsync_session_id": {
"type": "string",
"minLength": 1
},
"validationToken": {
"type": "string",
"minLength": 1
},
"new_token": {
"type": "string",
"minLength": 1
},
"newToken": {
"type": "string",
"minLength": 1
}
},
"additionalProperties": true,
"anyOf": [
{
"required": [
"instance_id"
]
},
{
"required": [
"machine_id"
]
}
],
"allOf": [
{
"anyOf": [
{
"required": [
"device_credential"
]
},
{
"required": [
"deviceCredential"
]
},
{
"required": [
"plugin_session_id"
]
},
{
"required": [
"pluginSessionId"
]
},
{
"required": [
"session_id"
]
},
{
"required": [
"sessionId"
]
},
{
"required": [
"soundSyncSessionId"
]
},
{
"required": [
"soundsync_session_id"
]
},
{
"required": [
"validation_token"
]
},
{
"required": [
"token"
]
},
{
"required": [
"validationToken"
]
},
{
"required": [
"new_token"
]
},
{
"required": [
"newToken"
]
}
]
}
]
}
HTTP 200 response (application/json)
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"status": {
"type": "string"
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"mayOpenProduct": {
"type": "boolean"
},
"activation_deactivated": {
"type": "boolean"
},
"plugin_session_deactivated": {
"type": "boolean"
},
"activation_id": {
"type": "integer",
"minimum": 1
},
"activationId": {
"type": "integer",
"minimum": 1
},
"current_activations": {
"type": "integer",
"minimum": 0
},
"max_activations": {
"type": "integer",
"minimum": 0
},
"remaining_activations": {
"type": "integer",
"minimum": 0
},
"serial_status": {
"type": "string"
}
},
"additionalProperties": true
}
Documented failures: 400, 401, 403, 404, 500, 503.
Operation errors: deactivate_validation_token_required, deactivate_validation_token_invalid, DEVICE_ACTIVATION_NOT_FOUND.
SoundSync
Access lifecycle
Keep audio/access decisions outside the network layer.
-
No local activation
Show activation UI. Do not unlock from missing or corrupt cache.
-
Claim or login
Collect serial/email or customer login according to product activation mode.
-
Final activation
Unlock only after /activate or /customer-login/activate returns an activated/allowed state.
-
Startup validation
Read encrypted cache and call /validate asynchronously.
-
Temporary failure
Use offline grace only if cache is valid and the failure is transport-level.
-
Hard denial
Lock immediately on explicit platform denial such as device_deactivated or subscription_payment_required.
-
Deactivation
Call /deactivate and delete local activation state.
