Edit a product, or rotate its key
const url = 'https://app.dycrypt.com/o/acme/api/products/1';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"productKey":"example","name":"example","description":"example","active":true,"params":[{"key":"example","label":"example","type":"STRING","required":true,"defaultValue":"example","options":["example"],"help":"example"}],"defaultValidityMonths":1,"defaultGraceDays":1,"licenceType":"OFFLINE","allowedLicenceTypes":["OFFLINE"],"checkIntervalSeconds":1,"maxOfflineSeconds":1,"fingerprintNeed":1,"maxMachines":1,"licenceFetchEnabled":true,"algorithm":"example","certificateType":"example","certificateSubject":"CN=Acme Suite, O=Acme","certificateValidityDays":3650,"regenerateKey":true,"privateKeyPem":"example","publicKeyPem":"example","keystoreFile":"example","keystoreType":"example","keystorePassword":"example","keyAlias":"example","keyPassword":"example","pkcs11Library":"example","pkcs11Slot":"example","pkcs11Pin":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://app.dycrypt.com/o/acme/api/products/1 \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "productKey": "example", "name": "example", "description": "example", "active": true, "params": [ { "key": "example", "label": "example", "type": "STRING", "required": true, "defaultValue": "example", "options": [ "example" ], "help": "example" } ], "defaultValidityMonths": 1, "defaultGraceDays": 1, "licenceType": "OFFLINE", "allowedLicenceTypes": [ "OFFLINE" ], "checkIntervalSeconds": 1, "maxOfflineSeconds": 1, "fingerprintNeed": 1, "maxMachines": 1, "licenceFetchEnabled": true, "algorithm": "example", "certificateType": "example", "certificateSubject": "CN=Acme Suite, O=Acme", "certificateValidityDays": 3650, "regenerateKey": true, "privateKeyPem": "example", "publicKeyPem": "example", "keystoreFile": "example", "keystoreType": "example", "keystorePassword": "example", "keyAlias": "example", "keyPassword": "example", "pkcs11Library": "example", "pkcs11Slot": "example", "pkcs11Pin": "example" }'Send regenerateKey: true to rotate a managed product’s key pair.
Rotation invalidates nothing already signed — but those licences only verify against the OLD public key. Ship the new public key before issuing anything with the new one.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”Create and update share one shape. Secrets — privateKeyPem, keystore
passwords, a PKCS#11 PIN — are write-only: sealed on the way in, never
present in any response.
object
One parameter a licence for this product carries. The parameter list IS the
licence’s shape: every value collected becomes a claim under key.
The issuer owns v, lid, prd, org, iat, exp and grace; a
product parameter may not shadow them.
object
The claim name in the signed JSON.
Allowed values, for ENUM.
See the licence-mode guides — Offline verifies alone, Online must check in, Hybrid does both.
At least one. Absent leaves it unchanged.
Required for ONLINE and HYBRID.
Must exceed the interval.
Rotate — generate a brand-new key pair for a managed product.
Import an existing PKCS#8 key instead of generating one.
The public half of an imported key — a public key PEM or a certificate PEM.
Responses
Section titled “Responses”The updated product.
object
Signed into every licence as prd.
The JDK name: Ed25519, SHA256withRSA, SHA256withECDSA.
Where the private key lives — managed
See the licence-mode guides — Offline verifies alone, Online must check in, Hybrid does both.
Public — it is in the URL every installed application calls.
Whether a check token exists. Never the token itself.
Whether /fetch is available for this product. Off by default.
How many of the five fingerprint components must match.
How many machines a licence for this product binds at once. The default for new licences only.
One parameter a licence for this product carries. The parameter list IS the
licence’s shape: every value collected becomes a claim under key.
The issuer owns v, lid, prd, org, iat, exp and grace; a
product parameter may not shadow them.
object
The claim name in the signed JSON.
Allowed values, for ENUM.
Whether the signing service can currently open this key.
Example
{ "algorithm": "ED25519", "licenceType": "OFFLINE", "allowedLicenceTypes": [ "OFFLINE" ], "params": [ { "type": "STRING" } ]}The request is wrong — a bad date, a missing field, a value the product does not declare.
Every failure in this API has this shape and no other.
object
Example
{ "error": "this token does not have licenses:write"}No credential, or one that no longer resolves — revoked, expired, deleted. Replace it.
Every failure in this API has this shape and no other.
object
Example
{ "error": "this token does not have licenses:write"}Authenticated, but not allowed: a missing scope, a read-only role, a plan limit reached, or a credential used under another organisation’s slug. The right credential doing something it may not do.
Every failure in this API has this shape and no other.
object
Example
{ "error": "this token does not have licenses:write"}No such record, or no such endpoint.
Every failure in this API has this shape and no other.
object
Example
{ "error": "this token does not have licenses:write"}