Skip to content

Sign a new term under the same licence id

POST
/api/licenses/{lid}/renew
curl --request POST \
--url https://app.dycrypt.com/o/acme/api/licenses/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/renew \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "issueDate": "2026-04-15", "startsOn": "2026-04-15", "validityMonths": 1, "graceDays": 1, "params": {} }'

The lid survives; the signed string does not. An installation still holding the old string needs the new one — through your own delivery path, or through /fetch if the product has self-service fetch turned on.

Send no body at all to renew on the product’s defaults.

lid
required
string format: uuid

The licence id — a UUID, and the lid claim in the signed payload. It survives renewal.

Media typeapplication/json

Send no body at all to renew on the product’s defaults.

object
issueDate
string format: date
startsOn
string format: date
validityMonths
integer
graceDays
integer
params
object
Examplegenerated
{
"issueDate": "2026-04-15",
"startsOn": "2026-04-15",
"validityMonths": 1,
"graceDays": 1,
"params": {}
}

The renewed licence.

Media typeapplication/json
object
lid
required
string format: uuid
customerId
integer | null format: int64
licensee
required

The customer’s name

string
licenseeEmail
string | null
productId
required
integer format: int64
productName
string | null
productKey

Signed into the licence as prd.

string | null
issuedAt
required
string format: date-time
startsAt

The nbf claim. Absent means it is valid immediately.

string | null format: date-time
expiresAt

Null for a perpetual licence — the exp claim is omitted entirely.

string | null format: date-time
graceDays
required
integer
licenceType
required

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

string
Allowed values: OFFLINE ONLINE HYBRID
activation

How a Hybrid licence first binds to a machine. Only meaningful for HYBRID.

string
Allowed values: ONLINE OFFLINE
activated
boolean
boundAt

When it bound to a machine. Null means nobody has installed it yet.

string | null format: date-time
rebindCount

How many times an operator released the binding.

integer
maxMachines

How many machines this licence binds at once. Copied from the product at issue.

integer
seatsUsed

How many of them are bound right now.

integer
status
required

Where the licence is against the calendar and the revocation flag. PENDING, EXPIRED and REVOKED do not count against plan capacity.

string
Allowed values: PENDING ACTIVE GRACE EXPIRED REVOKED
checkHealth

What the field says, beside what the calendar says. NOT_APPLICABLE for every Offline licence, which is most of them in a typical organisation.

string
Allowed values: NOT_APPLICABLE NEVER OK DUE OVERDUE
checkMaxSeconds

The signed offline window.

integer | null
checkEverySeconds

How often the application should check in.

integer | null
revoked
required
boolean
revokedReason
string | null
archived

Filed away — off the default list and out of renewal. Still verifies in the field.

boolean
archivedAt
string | null format: date-time
issuedBy

The person or token that issued it.

string
lastCheckedAt
string | null format: date-time
renewedAt
string | null format: date-time
claims

The signed payload, decoded. Issuer claims first, then the product’s own parameters.

object
licenseString

The artifact to deliver: payloadB64url.signatureB64url. This is what a customer’s application verifies, and its own signature is its proof.

string
notes

Free text. Never signed into the licence.

string | null
Example
{
"licenceType": "OFFLINE",
"activation": "ONLINE",
"status": "PENDING",
"checkHealth": "NOT_APPLICABLE"
}

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"
}

No such record, or no such endpoint.

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"
}