Guide
Customer Login Activation
Activate a machine with customer account identity using POST /api/license/v1/customer-login/activate.
Use the maintained account-login conversation
JUCE 0.7.3 and HISE Native C++ 0.5.2 handle customer sign-in before product activation. Regenerate and rebuild older plugins to obtain the updated client. Never ask a customer to turn off two-factor authentication.
POST /api/auth/login with email, password and role:customer. An account without two-factor protection can return its verified session immediately. An enabled account returns a private challenge, not a customer session. Continue with twoFactorToken and twoFactorCode; only the resulting account token belongs in the licensing customer_token field.
Keep challenge tokens, account tokens, passwords and codes out of logs, URLs, screenshots and the license cache. Run the conversation on the licensing worker, never the audio thread. The maintained client privately retains only the required licensing/device renewal state after activation.
SoundSync
Customer login, two-factor continuation and product activation
curl --fail-with-body -sS -X POST "$SOUNDSYNC_API_BASE/api/auth/login" \
-H "Content-Type: application/json" \
--data '{"email":"customer@example.com","password":"CUSTOMER_PASSWORD","role":"customer"}'
curl --fail-with-body -sS -X POST "$SOUNDSYNC_API_BASE/api/auth/login" \
-H "Content-Type: application/json" \
--data '{"email":"customer@example.com","twoFactorToken":"PRIVATE_CHALLENGE_TOKEN","twoFactorCode":"AUTHENTICATOR_OR_RECOVERY_CODE","role":"customer"}'
curl --fail-with-body -sS -X POST "$SOUNDSYNC_API_BASE/api/license/v1/customer-login/activate" \
-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 '{"customer_token":"VERIFIED_CUSTOMER_TOKEN","instance_id":"example-machine","device_credential_supported":true}'
SoundSync
Finish sign-in before activating a device
| Result | Next action |
|---|---|
| 200 twoFactorRequired:true | Keep the plugin locked. Continue /api/auth/login with the returned private twoFactorToken, an authenticator or unused recovery code, the same customer email and role:customer. Omit the password on this continuation. |
| 401 Invalid two-factor code | Retry a current authenticator or unused recovery code within the existing challenge. Do not restart activation or create another account. |
| Expired challenge / two_factor_expired | Choose Start again and enter the password. Native challenges last up to ten minutes and do not survive restarting the plugin. |
| 403 EMAIL_VERIFICATION_REQUIRED | Verify the customer account email through its supported account flow, then sign in again. Account verification and serial ownership verification are separate. |
| Verified login returns token | Pass that account token as customer_token to /api/license/v1/customer-login/activate for the matching product and machine. A challenge token is not this account token. |
| 401 TWO_FACTOR_REQUIRED from direct password activation | Use the two-step account login instead. The direct licensing email/password compatibility branch cannot finish two-factor authentication. |
| Entitlement or device-limit denial | Use the ownership, billing or device-management recovery path. Account sign-in alone does not unlock the product or create offline grace. |
SoundSync
Endpoint contract
Use canonical field names in new clients. Aliases are compatibility only.
/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. Maintained JUCE 0.7.2/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. 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.
SoundSync
Compatibility aliases
Accept aliases only to support older integrations; new docs and examples use canonical names.
| Canonical | Accepted aliases |
|---|---|
| customerEmail, customer_email, license_email, licenseEmail | |
| password | customerPassword, customer_password, loginSecret, login_secret, customerLoginSecret, customer_login_secret, accountPassword, account_password, accountSecret, account_secret, secret |
| customer_token | customerToken, customerJwt, customer_jwt |
| instance_id | machine_id, uid |
SoundSync
Failure behavior
Customer-login failures are explicit platform decisions, not offline-grace events.
| Failure | Expected behavior |
|---|---|
| Invalid login | Keep activation UI open. Do not cache password or unlock. |
| Customer not entitled | Show product ownership/support path. |
| subscription_payment_required | Lock access and route to billing/support. |
| Device limit reached | Show device management or support. |
| Product disabled or credential failure | Block activation and show developer diagnostic without exposing secrets. |
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.
SoundSync
Compatibility only: direct password activation without two-factor authentication
Standard custom HTTP/HISEScript product credentials are a different client identity path. This direct password example is not the maintained native login flow and returns TWO_FACTOR_REQUIRED for enabled accounts. Prefer verified customer-token activation.
curl -sS -X POST "$SOUNDSYNC_API_BASE/api/license/v1/customer-login/activate" \
-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 '{
"email": "customer@example.invalid",
"password": "do-not-cache-this",
"instance_id": "machine-demo-001",
"product_id": 23794,
"plugin_version": "1.0.0"
}'
Account sessions must be verifiable
A signed account token is not enough on its own: customer account requests also check that the session is still allowed. If that check is unavailable, protected library, invoice, review, device-reset, download and customer-token activation requests stop before returning private data or performing the protected action.
503 SESSION_VERIFICATION_UNAVAILABLE means verification could not finish. Retry after service recovery; it does not mean that the purchase disappeared or the session was confirmed revoked. A confirmed revoked session returns 401 LIBRARY_SESSION_REVOKED and requires sign-in again. Do not grant access on either response.
Shared library/download tokens retain their separate token and ownership checks. Optional storefront personalization can fall back to anonymous browsing when customer identity cannot be established; that does not authorize a private download. This account-session check does not replace the signed JUCE offline-grant policy.
