Skip to content

Submit a licensing request

POST /api/integrations/v1/licensing-requests

Use this endpoint after your own commercial process has approved an order. You execute the PO, contract or invoice outside LicenChain, then submit the approved order data — never the PO document itself. LicenChain creates a licensing request and returns a single-use Buyer onboarding link that you send to the Buyer contact.

Product terms are predefined on the registered product. The Buyer reviews and accepts the applicable terms version inside LicenChain; there is no second checkout.

Terminal window
curl --request POST "$LICENCHAIN_API_BASE_URL/api/integrations/v1/licensing-requests" \
--header "Authorization: Bearer $LICENCHAIN_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: 5d1f8a3c-2b7e-4c49-9f0a-6e3b2d4c8a17" \
--data '{
"externalOrderId": "SELLER-PO-EXAMPLE-001",
"productRef": "ai-specialist-standard",
"buyer": {
"organizationName": "Example Research Cooperative",
"contactEmail": "licensing@example.com"
},
"price": {
"currency": "EUR",
"netLicensedAmount": "1200.00"
},
"validity": {
"validFrom": "2027-01-01T00:00:00Z",
"validUntil": "2028-01-01T00:00:00Z"
},
"quantity": 25
}'
Header Required Description
Authorization Yes Bearer <Seller API key>. See Authentication.
Content-Type Yes application/json
Idempotency-Key Yes Unique per logical order submission (UUID v4 recommended). Reuse it for every retry of the same order.
Field Type Description
externalOrderId string Your PO, contract or order reference. Unique per Seller; used for traceability and duplicate detection. 1–100 characters: letters, digits and . _ : / -.
productRef string Reference of a product registered on your Seller account. Its predefined terms apply.
buyer.organizationName string Legal or trading name of the corporate Buyer.
buyer.contactEmail string Buyer contact who will receive the onboarding link from you. Personal data — see below.
price.currency string ISO 4217 code, for example EUR.
price.netLicensedAmount string Net licensed amount excluding VAT, as a decimal string with exactly two fraction digits, for example "1200.00". Never send a floating-point number.
validity.validFrom string Start of the license period, inclusive. UTC timestamp ending in Z.
validity.validUntil string End of the license period, exclusive. UTC timestamp ending in Z, later than validFrom.
quantity integer, optional Seat or unit allowance within the single corporate license issued for this request (1–10,000), for example the number of named users the Buyer may assign. Omit it for products without an allowance. It never creates more than one license.

The first contract version covers one product per request and a corporate Buyer. Named end users are not required: user assignment happens later in your own delivery system. Do not attach the PO document or other contract files.

Each licensing request results in exactly one issued corporate license with one canonical licenceKey, whatever the quantity:

Concept Meaning
License The corporate license issued to the Buyer organization for one product, identified by one licenceKey.
quantity (request) Optional seat or unit allowance recorded on that license.
seatLimit (licence.issued) The same allowance as recorded at issuance, or null when the product has none.
Named users / seats Assigned and enforced by your delivery system against seatLimit. LicenChain does not create a license per seat.

price.netLicensedAmount is the net amount for the whole license. LicenChain derives no amount from quantity. Issuing separate licenses for individual seats is not part of this contract; it would require an explicit future business-model decision.

Orders with several lines (future evolution)

Section titled “Orders with several lines (future evolution)”

externalOrderId is unique per Seller, and in this version one order maps to one product, one licensing request and one license. If a PO has several product lines, it cannot yet be submitted as one order. Multi-line support is intentionally left open; it is expected to be additive — for example an optional per-line reference used together with externalOrderId for duplicate detection, or a parent order with line items — so that existing single-product integrations remain valid. No such field exists in this contract version; do not send one.

{
"schemaVersion": "1.0",
"requestId": "lreq_7Q2M9K4X8P3D",
"externalOrderId": "SELLER-PO-EXAMPLE-001",
"productRef": "ai-specialist-standard",
"termsVersion": "2026.2",
"status": "awaiting_buyer",
"onboarding": {
"url": "https://sandbox.licenchain.example/onboarding/REDACTED-ONE-TIME-TOKEN",
"expiresAt": "2026-12-08T09:00:00Z"
},
"createdAt": "2026-11-08T09:00:00Z"
}
Field Description
requestId LicenChain identifier of the licensing request. Store it with your order.
termsVersion The product terms version the Buyer will be asked to accept.
status State of the request: awaiting_buyer, onboarding_completed, issued, expired or cancelled.
onboarding.url Single-use Buyer onboarding link.
onboarding.expiresAt When the link stops working (UTC).

Retrying with the same Idempotency-Key and the same body returns the original result with 200 and the header Idempotent-Replayed: true. No second request is created.

Situation Result
Same Idempotency-Key, same body 200 with the original response (Idempotent-Replayed: true).
Same Idempotency-Key, different body 409 idempotency_key_reused.
New Idempotency-Key, externalOrderId already submitted 409 duplicate_external_order with existingRequestId.

Idempotency keys are retained for at least 24 hours. Generate the key when you first create the order submission and persist it, so a crash or timeout can be retried safely.

Errors use RFC 9457 problem details. Example validation error:

400 Bad Request
{
"type": "https://developers.licenchain.io/api/docs/errors/#validation_failed",
"title": "Request validation failed",
"status": 400,
"code": "validation_failed",
"detail": "One or more fields are invalid.",
"traceId": "trc_4H8K2M6Q9R",
"errors": [
{
"field": "price.netLicensedAmount",
"code": "invalid_decimal",
"message": "Use a decimal string with exactly two fraction digits, for example \"1200.00\"."
}
]
}
Status code What to do
400 validation_failed Fix the fields listed in errors[]. Do not retry unchanged.
401 unauthenticated Check or rotate the API key.
403 forbidden The key is not permitted to submit licensing requests.
404 product_not_found productRef is not a registered product of your Seller account.
409 duplicate_external_order / idempotency_key_reused See the table above.
429 rate_limited Wait for Retry-After, then retry with the same Idempotency-Key.
503 service_unavailable Retry with backoff and the same Idempotency-Key.

buyer.contactEmail is personal data. Send only a business contact needed for onboarding, prefer role mailboxes where possible, and avoid copying it into logs. LicenChain never returns it in error responses or webhook payloads.

The Buyer opens the link, signs in or creates an account, and accepts the terms. You then receive onboarding.completed and later licence.issued, which delivers the licenceKey. Keep requestId and externalOrderId with your order: they are your references if an issuance event is ever missed. See the Licensing lifecycle.