Skip to content

Powered by Grav CMS + Helios Theme

Licenses (add-on)

Issuing, editing, suspending, revoking and regenerating license keys, and freeing a seat.

Provided by the KahunaCart Licenses plugin. One permission covers the whole admin API, because a licence key is the credential itself and reading the list is already handing out the goods. See Licenses.

List licenses

GET /api/v1/kahunacart/licenses Permission kahunacart.licenses

Search issued license keys, newest first, each with its status, its project name, the seats in use against the seats allowed, its product, its order, its customer and its two dates. q matches a fragment of a key, the project name the customer gave it, a buyer's email or an order number, which are the four things a support conversation ever starts with. Status expired is derived from the expiry date every time it is asked and is never stored, so an expired key appears under expired and not under active. Use get_license for one key with its activations and the delivery copy the customer was sent.

Parameters

Name Type Description
q optional string Substring match on the key, its project name, the customer's email or the order number
status optional string Anything else is ignored rather than refused
One of: active, suspended, revoked, expired
product_id optional integer Only keys for this catalog product
variant_id optional integer Only keys for this variant
customer_id optional integer Only keys belonging to this customer
order_id optional integer Only keys minted by this order
page optional integer At least 1.
Default: 1
per_page optional integer Clamped to 200, and the clamped value comes back in the response
Default: 25
sort optional string A column to sort every matching key by before the page is cut; leave out for newest first
One of: key, project, product, status, seats, customer, order, expires
dir optional string
One of: asc, desc
Default: asc

Response

Answers {licenses, total, page, per_page, statuses}.

Get a license

GET /api/v1/kahunacart/licenses/{id} Permission kahunacart.licenses

One key with everything it knows about itself: the row and its effective status, every machine it has been activated on including the seats already freed, the product, variant, customer and order behind it, the licensing rule that governs it, every add-on that has been bought onto it, and a preview of the delivery copy and license files the customer receives. Call this before suspending, revoking or freeing a seat, because the activation ids free_license_seat needs are only here.

Parameters

Name Type Description
id required integer License id, not the key itself

Issue a license by hand

POST /api/v1/kahunacart/licenses Permission kahunacart.licenses

Mint a key with no order behind it, for a comp, a review copy or a replacement for somebody who bought through another channel, and return it the way get_license does. No order is invented to hang it on, so nothing lands in the store's revenue reports. A product is required and an unknown product, an unknown customer or a variant belonging to a different product answers 422. Name the owner by customer_id or by email; an email that already has an account gets the key on that account and a new one gets an account. seats, term_days and updates_days fall back to the store defaults when omitted, and sending any of them as null means unlimited seats, a perpetual key or updates forever. The key is drawn in the product rule's own layout and carries its prefix, so a comp key looks like the product's other keys, and the same delivery email an order-issued key triggers goes out.

Parameters

Name Type Description
product_id required integer Catalog product the key is for
variant_id optional integer Must belong to product_id; picks the variant's own licensing rule
customer_id optional integer Existing customer to give the key to
email optional string Used only when customer_id is absent. An address with an account gets the key on it; a new address gets an account
seats optional integer or null Machines that may hold the key at once. null is unlimited, omitted is the store default
term_days optional integer or null Days until the key expires. null is perpetual, omitted is the store default
updates_days optional integer or null Days of updates entitlement, which is separate from the term. null is updates forever, omitted is the store default
meta optional object Free-form object handed back to the customer's software on every validation
note optional string Private note, never shown to the customer

Edit a license

PATCH /api/v1/kahunacart/licenses/{id} Permission kahunacart.licenses

Change what a merchant is allowed to change on an issued key: the project name, the seat allowance, the expiry, the updates window, the private note, the metadata and who it belongs to. Only the fields sent are touched, and a null on seats, expires_at or updates_until clears the limit rather than zeroing it. Lowering seats below the machines already holding one is refused with 409 seats_below_live, and the whole request is left unapplied when that happens, so a rejected seat change never half-saves the expiry beside it. Pushing the two dates out is how an operator extends a key by hand; a customer buying more time does it through a renewal product instead, which extends from max(now, current updates_until) and writes the extension on the order.

Parameters

Name Type Description
id required integer License id
label optional string The customer's own name for this key — the project or site it runs on. The customer edits it from their account too. An empty string clears it
seats optional integer or null null is unlimited. Refused when lower than the live activations
expires_at optional integer or null Unix timestamp the key expires on. null is perpetual
updates_until optional integer or null Unix timestamp the updates window closes on. null is forever. A closed window does not stop the key validating
customer_id optional integer or null Move the key to another customer. null detaches it from every account
meta optional object Replaces the whole metadata object. null or an empty object clears it
note optional string Private note, never shown to the customer. Empty clears it

Suspend a license

POST /api/v1/kahunacart/licenses/{id}/suspend Permission kahunacart.licenses

Switch a key off for now, which is the one to use for a chargeback under investigation or a customer in arrears. Validation starts answering valid: false with status suspended, and the activations are left in place on purpose so reinstate_license puts the customer back exactly where they were rather than making them reactivate twelve machines by hand. Suspending an already suspended key is a no-op success; a revoked key answers 409 invalid_transition, because revocation is permanent. Returns the same payload get_license does.

Parameters

Name Type Description
id required integer License id
note optional string Private note recorded against the key, never shown to the customer

Reinstate a license

POST /api/v1/kahunacart/licenses/{id}/reinstate Permission kahunacart.licenses

Undo a suspension and put the key back to active with its activations untouched. Reinstating an already active key is a no-op success. A revoked key cannot be reinstated and answers 409 invalid_transition: revocation exists precisely so a key can stop working permanently, and issue_license or regenerate_license is the way to give the customer a working key again. Returns the same payload get_license does.

Parameters

Name Type Description
id required integer License id

Revoke a license

POST /api/v1/kahunacart/licenses/{id}/revoke Permission kahunacart.licenses

Kill a key permanently and free every seat it holds. There is no way back from this: a revoked key cannot be suspended, reinstated or renewed, it has no license files, and the only remedy for a mistake is issuing a new key. A reason is required and is kept on the record forever, because "revoked, nobody remembers why" is a support ticket waiting to happen. Revoking an already revoked key answers 409 revoked. Prefer suspend_license for anything reversible. Returns the same payload get_license does.

Parameters

Name Type Description
id required integer License id
reason required string Why the key is being killed. Required, kept on the record, and an empty one answers 422

Regenerate a license key

POST /api/v1/kahunacart/licenses/{id}/regenerate Permission kahunacart.licenses

Replace a leaked key. The current key is revoked rather than deleted, so software still holding it is told plainly that it is dead, and a fresh key is minted carrying the same order, customer, product, variant, seats and dates, drawn in the product rule's own layout. This is destructive on the old key and cannot be undone. The response is the new key's get_license payload with the revoked one under previous.

Parameters

Name Type Description
id required integer License id

Free an activation seat

DELETE /api/v1/kahunacart/licenses/{id}/activations/{activationId} Permission kahunacart.licenses

Release one seat on the customer's behalf, which is the support action for a machine that died still holding one. The activation row is kept and marked deactivated rather than deleted, so the history of which machines the key has been on stays intact. Get the activation id from get_license; an id belonging to another key answers 404. Returns whether a seat was actually freed, the new seat counts and the full activation list.

Parameters

Name Type Description
id required integer License id
activationId required integer Activation id, from get_license

A refusal from the licensing service carries a stable machine code in the body and in an X-KahunaCart-Error header.