Guide
Deactivation
Understand JUCE local deactivation, pending server confirmation, device-slot release, and the deactivation API.
Offline grace and deactivation are different
Offline grace keeps a previously authorized plugin usable during a connection outage, within its verified signed deadline. It is not a deactivation option and cannot override a local deactivation block. Expired grace locks access until successful authorization; it does not deactivate the device or free a device slot.
JUCE immediately locks audio and saves deactivation intent. The local block persists across restarts and shared instances. While deactivation is pending, the maintained runtime keeps the protected proof needed to finish the request and retries when it reconnects; do not delete that proof or remove the block to restore grace.
If secure storage cannot save the intent, keep audio locked, resolve deactivation_storage_failed and retry. Do not report completed deactivation or promise a saved pending request when storage failed.
Only server confirmation proves that this machine was deactivated and its device slot released. Until then, show deactivation_pending rather than claiming the slot is available elsewhere. Other integrations must follow their own documented local-lock and retry behavior; the HTTP endpoint itself requires a connection.
SoundSync
Endpoint contract
Send product credential headers and the current machine identity.
/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
- 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. 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"
},
"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"
]
},
"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"
},
"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.
SoundSync
Deactivation example
This direct HTTP example requires a connection. Clear activation proof only after confirmed server deactivation. JUCE handles its protected pending proof, cache cleanup and persistent local block through the maintained runtime; do not manually erase its state.
curl -sS -X POST "$SOUNDSYNC_API_BASE/api/license/v1/deactivate" \
-H "Content-Type: application/json" \
-H "x-ss-app-id: ss_prod_demoapp123" \
-H "x-ss-plugin-key: ss_pk_demokey123" \
-H "x-ss-plugin-secret: ss_ps_demosecret123" \
-d '{
"license_key": "DEMO-SERIAL-0001",
"instance_id": "machine-demo-001",
"product_id": 23794
}'
SoundSync
Client behavior
Deactivation affects the machine activation, not the serial itself.
| Question | Answer |
|---|---|
| Does it free a device slot? | Successful server deactivation marks the activation deactivated and returns remaining activations; policy determines reuse. A local lock or pending request alone does not prove slot release. |
| What should be deleted? | After confirmed server deactivation, clear the old activation proof and grace state. Let JUCE perform its own cleanup while preserving the local block; do not delete protected proof while deactivation is pending. |
| Does the serial remain valid? | The serial can remain valid unless the serial itself is revoked/deactivated/expired. |
| Can the user reactivate immediately? | Complete pending JUCE deactivation first. Reactivation then depends on product policy, entitlement, subscription, and device limits. |
| Can deactivation happen offline? | JUCE can lock locally and persist a pending deactivation offline. Reconnect to complete server deactivation; only server confirmation proves device-slot release. Offline grace cannot override that local block. |
Package-specific access policy
JUCE 0.7.3 supports signed offline access for the grace period selected in product Access settings, through 90 days. A prior successful activation or validation and the matching package verification keys are required. Startup uses a verified unexpired grant or online authorization. Zero, disabled, missing or expired grace requires online authorization; confirmed denial or deactivation locks access. Regenerate and rebuild older plugins to use this release.
Customer activation resets, when enabled
Developers can allow customer self-service resets for supported serial and entitlement licenses, with a configured cooldown. Only the signed-in owner of the license can request a reset. The confirmation clears the affected device activations and sessions together while preserving the license and product ownership.
A reset is not a refund, a new serial, or unlimited extra devices. Customers must reload the current state and wait for the next eligible reset when a cooldown applies.
SoundSync
Native server deactivation request
curl --fail-with-body -sS -X POST "$SOUNDSYNC_API_BASE/api/license/v1/deactivate" \
-H "x-ss-app-id: $APP_ID" \
-H "x-ss-product-id: $PRODUCT_ID" \
-H "x-soundsync-public-client: juce-native" \
-H "Content-Type: application/json" \
--data '{"instance_id":"example-machine","device_credential":"DEVICE_CREDENTIAL_FROM_AUTHORIZED_RESPONSE"}'
Confirm the deactivation, not only the request
A confirmed response includes status:deactivated, code:DEVICE_DEACTIVATED and activation_deactivated:true; native session deactivation can also report plugin_session_deactivated:true and remaining_activations. No fresh offline grant is issued. Do not treat any HTTP 200 or an unconfirmed body as proof that the device slot was released.
An unavailable/expired plugin session can return 401 plugin_session_invalid on validation. Keep a valid durable device credential for renewal and follow confirmed entitlement/device denials separately. Deactivation can return 404 DEVICE_ACTIVATION_NOT_FOUND; reconcile the actual activation state rather than claiming a successful release. JUCE keeps its local pending block and protected proof until completion. These illustrative requests do not replace that runtime.
