Skip to content

Create a product

POST
/api/products
curl --request POST \
--url https://app.dycrypt.com/o/acme/api/products \
--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" }'

Generates a signing key unless one is imported. The private half is sealed by the cipher service and never returned by any endpoint in this document.

Refused with 403 if the plan’s key limit is reached.

Media typeapplication/json

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
productKey
string
name
string
description
string
active
boolean
params
Array<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
key

The claim name in the signed JSON.

string
label
string
type
string
Allowed values: STRING INTEGER BOOLEAN DATE STRING_LIST ENUM
required
boolean
defaultValue
string | null
options

Allowed values, for ENUM.

Array<string>
help
string | null
defaultValidityMonths
integer
defaultGraceDays
integer
licenceType

See the licence-mode guides — Offline verifies alone, Online must check in, Hybrid does both.

string
Allowed values: OFFLINE ONLINE HYBRID
allowedLicenceTypes

At least one. Absent leaves it unchanged.

Array<string>
Allowed values: OFFLINE ONLINE HYBRID
checkIntervalSeconds

Required for ONLINE and HYBRID.

integer
maxOfflineSeconds

Must exceed the interval.

integer
fingerprintNeed
integer
maxMachines
integer
>= 1
licenceFetchEnabled
boolean
algorithm
string
certificateType
string
certificateSubject
string
certificateValidityDays
integer
default: 3650
regenerateKey

Rotate — generate a brand-new key pair for a managed product.

boolean
privateKeyPem

Import an existing PKCS#8 key instead of generating one.

string
publicKeyPem

The public half of an imported key — a public key PEM or a certificate PEM.

string
keystoreFile
string
keystoreType
string
keystorePassword
string
keyAlias
string
keyPassword
string
pkcs11Library
string
pkcs11Slot
string
pkcs11Pin
string

The new product.

Media typeapplication/json
object
id
required
integer format: int64
productKey
required

Signed into every licence as prd.

string
name
required
string
description
string | null
active
required
boolean
algorithm
required
string
Allowed values: ED25519 RSA_2048 RSA_3072 RSA_4096 EC_P256 EC_P384
algorithmLabel
string
signatureAlgorithm

The JDK name: Ed25519, SHA256withRSA, SHA256withECDSA.

string
certificateType
string
keyOrigin

Where the private key lives — managed

string
keyFingerprint
string | null
certificateExpiresAt
string | null format: date-time
certificateExpired
boolean
paramCount
integer
licenseCount
integer format: int64
licenceType
required

See the licence-mode guides — Offline verifies alone, Online must check in, Hybrid does both.

string
Allowed values: OFFLINE ONLINE HYBRID
allowedLicenceTypes
Array<string>
Allowed values: OFFLINE ONLINE HYBRID
checkId

Public — it is in the URL every installed application calls.

string | null
checkTokenSet

Whether a check token exists. Never the token itself.

boolean
checkRotatedAt
string | null format: date-time
licenceFetchEnabled

Whether /fetch is available for this product. Off by default.

boolean
checkIntervalSeconds
integer | null
maxOfflineSeconds
integer | null
fingerprintNeed

How many of the five fingerprint components must match.

integer | null
maxMachines

How many machines a licence for this product binds at once. The default for new licences only.

integer
defaultValidityMonths
integer | null
defaultGraceDays
integer | null
createdAt
string format: date-time
params
Array<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
key

The claim name in the signed JSON.

string
label
string
type
string
Allowed values: STRING INTEGER BOOLEAN DATE STRING_LIST ENUM
required
boolean
defaultValue
string | null
options

Allowed values, for ENUM.

Array<string>
help
string | null
publicKeyPem
string | null
certificatePem
string | null
certificateSubject
string | null
keyState

Whether the signing service can currently open this key.

string | null
keyError
string | null
createdBy
string | null
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.

Media typeapplication/json

Every failure in this API has this shape and no other.

object
error
required
string
Example
{
"error": "this token does not have licenses:write"
}

No credential, or one that no longer resolves — revoked, expired, deleted. Replace it.

Media typeapplication/json

Every failure in this API has this shape and no other.

object
error
required
string
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.

Media typeapplication/json

Every failure in this API has this shape and no other.

object
error
required
string
Example
{
"error": "this token does not have licenses:write"
}