Skip to content

Verify a license

POST /api/integrations/v1/licenses/verify

Call this endpoint from your backend before granting new access to your licensed offering — a new session, a new token, or a tool call that is not covered by a recent check.

Use the canonical licenceKey delivered at issuance in the licence.issued event. Store it exactly as received and treat it as opaque. For NFT-backed licenses it has the form chainId:contractAddress:tokenId:

{ "licenceKey": "11155111:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:42" }

Do not create your own license ID, and do not substitute an order ID, requestId or transactionId.

Terminal window
curl --request POST "$LICENCHAIN_API_BASE_URL/api/integrations/v1/licenses/verify" \
--header "Authorization: Bearer $LICENCHAIN_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"licenceKey": "11155111:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:42"
}'
200 OK
{
"schemaVersion": "1.0",
"licenceKey": "11155111:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:42",
"productRef": "ai-specialist-standard",
"buyerOrganizationId": "org_2B5D8F1H4K7M",
"licenceHolderId": "org_2B5D8F1H4K7M",
"seatLimit": 25,
"issued": true,
"valid": true,
"status": "active",
"reason": null,
"validFrom": "2027-01-01T00:00:00Z",
"validUntil": "2028-01-01T00:00:00Z",
"checkedAt": "2027-03-15T10:30:00Z",
"revision": 3
}

When LicenChain has issuance evidence but no authoritative current lifecycle state for the license, it fails closed:

200 OK — deny
{
"schemaVersion": "1.0",
"licenceKey": "11155111:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:42",
"productRef": "ai-specialist-standard",
"buyerOrganizationId": "org_2B5D8F1H4K7M",
"licenceHolderId": "org_2B5D8F1H4K7M",
"seatLimit": 25,
"issued": true,
"valid": false,
"status": "unverified",
"reason": "lifecycle_state_missing",
"validFrom": null,
"validUntil": null,
"checkedAt": "2027-03-15T10:30:00Z",
"revision": null
}
200 OK — deny
{
"schemaVersion": "1.0",
"licenceKey": "11155111:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:42",
"productRef": "ai-specialist-standard",
"buyerOrganizationId": "org_2B5D8F1H4K7M",
"licenceHolderId": "org_2B5D8F1H4K7M",
"seatLimit": 25,
"issued": true,
"valid": false,
"status": "expired",
"reason": "validity_period_ended",
"validFrom": "2027-01-01T00:00:00Z",
"validUntil": "2028-01-01T00:00:00Z",
"checkedAt": "2028-01-02T08:00:00Z",
"revision": 4
}
Field Description
valid The only field that may permit access (license half). true only when status is active and checkedAt is inside the validity period.
issued Issuance evidence exists for this license. This is licensing evidence, not proof that the license is currently active.
productRef Registered product associated with the issued corporate license.
buyerOrganizationId LicenChain ID of the purchasing Buyer organization.
licenceHolderId LicenChain ID of the organization holding the license rights; this may differ from the Buyer.
seatLimit Seat or unit allowance inside this one corporate license, or null when not applicable. Your delivery system enforces named-user assignments and limits.
status active, not_yet_valid, expired, suspended, revoked or unverified.
reason null when valid. Otherwise lifecycle_state_missing, validity_period_not_started, validity_period_ended, suspended or revoked. New values may be added — treat unknown values as deny.
validFrom Start of the license period (UTC, inclusive), or null if unknown.
validUntil End of the license period (UTC, exclusive), or null if unknown.
checkedAt When LicenChain evaluated the state (UTC).
revision Monotonic lifecycle revision, or null if unknown. Higher revisions supersede lower ones.

Product, Buyer, holder and seat-limit references come from the issued license record and are returned only within the authenticated Seller’s scope. They may still be known when current lifecycle status is unverified: that does not make the license valid. These fields are informational and never replace your own customer, seat and user-authorization checks.

Outcome New access
200 and valid === true Allowed, if your own user checks also pass
200 and valid === false (any status) Deny
404 licence_not_found (unknown, or belongs to another Seller) Deny
400, 401, 403 Deny and alert — this is an integration fault
429, 503, timeout, network error Deny new access; retry later

Results are never cached by LicenChain (Cache-Control: no-store). If you cache a positive result to reduce latency, keep the cache short, key it by licenceKey, never cache a positive result past validUntil, and never extend it after a failed check. Lifecycle changes such as suspension or revocation are reflected on the next successful check; no propagation time is guaranteed in this target contract.

404 Not Found
{
"type": "https://developers.licenchain.io/api/docs/errors/#licence_not_found",
"title": "License not found",
"status": 404,
"code": "licence_not_found",
"detail": "No license with this licenceKey is visible to your Seller account.",
"traceId": "trc_4H8K2M6Q9R"
}

See Errors & retries for the full list.

The request contains only the canonical licenceKey. The response includes opaque organization identifiers, not Buyer names or contact emails. Treat those IDs as confidential metadata and never expose them to an AI agent or unauthorized Seller. Do not log API keys. Logging licenceKey, status, reason and traceId is sufficient for routine troubleshooting.