Licence check API
The Java, Node.js, and Python SDKs call the licence check API for Online and Hybrid licences. Prefer the SDK instead of implementing this protocol yourself: the SDK verifies the signed response for you, and an integration that skips that step enforces nothing.
The endpoint belongs to one product and requires that product’s check credentials. Copy both from the product’s Quick Start Guide.
Both endpoints on this page also appear in the endpoint reference, generated from the OpenAPI specification.
Request
Section titled “Request”POST /o/{slug}/api/public/license/{checkId}/checkAuthorization: Bearer dycc_<checkId>_<secret>Content-Type: application/json
{ "license": "<complete licence string>", "fingerprint": "DYC1.<hashed parts>.<checksum>", "nonce": "<fresh random value, 16-128 URL-safe characters>"}The request sends the complete signed licence and the current machine’s fingerprint. The fingerprint contains separately hashed component values, never the raw identifiers.
Generate a new nonce for every request. It comes back inside the signature, which is what stops a captured response from being replayed later.
The first successful check binds an Online or online-activated Hybrid licence. A later fingerprint from another machine is rejected without replacing the existing binding.
Response
Section titled “Response”{ "status": "ACTIVE", "valid": true, "lid": "24ec2229-0d0c-41f8-9eed-439fd5b5b789", "boundAt": "2026-08-14T09:11:00Z", "checkedAt": "2026-08-20T07:00:00Z", "serverTime": "2026-08-20T07:00:00Z", "nonce": "<the nonce you sent>", "receipt": "<base64url signature>"}Depending on the licence, the response may include expiry, grace, revocation time and reason, or other status context. Null fields can be omitted.
Possession of a correctly signed licence is the credential for the licence itself. The service verifies it before looking up its record so arbitrary licence IDs cannot be enumerated.
The receipt
Section titled “The receipt”receipt is a signature by the product’s own key — the same key that signed the licence, so your application already holds the public half and needs nothing new to check it.
It covers these fields, in this order, separated by the ASCII unit separator 0x1F:
DYCR1 · lid · status · nonce · checkedAt · boundAt · fpDigestfpDigest is the first 32 hexadecimal characters of SHA-256 over the fingerprint string you sent, which is what keeps a receipt from being carried to another machine. Absent fields are empty, never the word null.
An answer whose receipt does not verify is not an answer. The SDKs do not record it as a successful check, do not cache it, and let the licence continue toward STALE.
The check token
Section titled “The check token”The token ships inside the application you distribute, so treat it as identifying rather than secret. Anyone holding your software can extract it. What it buys is still worth having:
- the endpoint is no longer anonymous;
- a product’s check access can be revoked without reissuing its licences;
- rate limits apply per product as well as per address.
It is not what makes an answer trustworthy. The receipt is. Rotate the token from the product page at any time; the new value is shown once.
Error handling
Section titled “Error handling”The SDK combines the verified local result with the response and enforces the signed offline window. Timeouts, disabled checking, rate limits, service errors, a missing or wrong token (401), and an unverifiable receipt are all reported as an unavailable online answer rather than a successful status.
Do not send a licence that already failed local verification. The official SDKs perform this check before making the request.
Self-service licence fetch
Section titled “Self-service licence fetch”Renewal keeps a licence’s lid and re-signs a new string with a new exp. The check endpoint above can only detect that a renewal happened — the response stays valid: false with status: "ACTIVE" — it never carries the new string. The fetch endpoint closes that loop: an application can ask for the current signed string itself, presenting a licence it already holds (the current one, or an earlier, superseded one for the same lid) as the credential.
It is opt-in per product, off by default. A vendor who distributes licences through an existing flow — email, a download portal — keeps doing that unless the product turns this on from its Check credentials panel.
POST /o/{slug}/api/public/license/{checkId}/fetchAuthorization: Bearer dycc_<checkId>_<secret>Content-Type: application/json
{ "license": "<a licence string for this lid, current or superseded>", "fingerprint": "DYC1.<hashed parts>.<checksum>"}Same credential as check, and the same fingerprint rule: for a bound Online or Hybrid licence, the presented fingerprint must match the existing binding — there is no trust-on-first-use here, unlike the very first check. Offline licences have no check path at all, so there is nothing that would ever call this endpoint for one.
{ "license": "<the current signed licence string>"}Refused once the presented licence is past its own exp plus its grace period. Without that rule, holding any past licence file for a lid — even a leaked one — would let someone keep pulling whatever is current, forever, and expiry would stop being a delivery checkpoint. The cost is accepted deliberately: fetch is least useful exactly when an installation has already gone stale, which is when the existing “install the new file by hand” path is the fallback.
There is no policy to configure, unlike check. Call it whenever it makes sense — typically right after check() reports the renewed-but-not-installed case above, or on whatever schedule the application already owns — never automatically inside verify() or check() itself.