Skip to main content

Code Heaven Developer License API

The Developer License API is the server-to-server interface vendors use to license their own plugins through Code Heaven. When a customer buys your plugin on the Code Heaven marketplace, Code Heaven issues a license. Your plugin then calls this API to confirm the license is real, activate the customer's domain, and serve updates.

You do not have to build a licensing server, a key generator, an activation database, or an update CDN. Code Heaven runs all of that. Your plugin makes a handful of HTTPS calls and acts on the answers.

This API is not the buyer-facing OAuth flow customers use to log in to their dashboard. It is a vendor credential — a single secret key, scoped to you, that authorizes calls on behalf of every license you have sold. See Authentication for how that key works.

What the API is for​

The API exists to answer four questions your plugin needs answered at runtime:

  1. Is this license valid right now? A customer pasted a key into your settings screen. Is it real, paid-up, and entitled to this product? See Quickstart.
  2. Is this specific domain allowed to use it? A license is sold for a fixed number of sites. Activating, checking, and releasing domains is the license lifecycle.
  3. Is there a newer version, and where do I get it? Your plugin polls for updates and downloads the package from a short-lived signed URL.
  4. How do I do all of the above without rewriting HTTP plumbing? Use the PHP SDK.

The license model​

Every sale produces exactly one license key — an opaque string Code Heaven generates at checkout. The key is the unit of entitlement. It belongs to one buyer, references one product, and carries the terms of that purchase.

A license has three properties your code cares about:

ConceptMeaning
KeyThe per-purchase secret the customer holds. They paste it into your plugin.
ProductThe plugin this license entitles. A buyer who owns three of your plugins has three keys.
StatusThe license's current standing: valid, expired, revoked, or — for a key that is fine but not yet bound to the requesting site — domain_not_activated.

Per-purchase key plus domain activations​

A single key is not a free pass to install on unlimited sites. Each license carries a seat limit — the number of distinct domains that may run the plugin at once. A "seat" is a domain.

license key ──┬──> activation: example.com (seat 1)
├──> activation: staging.example.com (seat 2)
└──> activation: client-site.io (seat 3)
seatLimit: 3 → no seats left

When a customer installs your plugin and enters their key, your plugin activates their domain — it claims a seat. Code Heaven records the domain and the timestamp. When the customer moves a site or retires one, your plugin deactivates that domain to free the seat.

This is why validation is always tied to a domain. A key can be perfectly valid and still be refused on a given site because that site has not claimed a seat (domain_not_activated) or because every seat is already taken (seat_limit_exceeded). The license lifecycle page walks through every state.

The five endpoints​

All requests go to the base URL and authenticate with your vendor key:

Base URL: https://api.code-heaven.com/v1
Header: X-CH-Vendor-Key: <your vendor key>
MethodPathPurpose
POST/licenses/validateCheck a key + domain and read its status, expiry, and activations
POST/licenses/{licenseKey}/domainsActivate a domain (claim a seat)
DELETE/licenses/{licenseKey}/domains/{domain}Deactivate a domain (release a seat)
GET/licenses/{licenseKey}/updatesAsk whether a newer version exists
GET/licenses/{licenseKey}/downloadGet a short-lived signed URL for the package

A typical integration​

A complete plugin integration looks like this:

  1. The customer enters their license key in your plugin's settings screen.
  2. Your plugin calls POST /licenses/{key}/domains to activate the current domain, then POST /licenses/validate to confirm and cache the result.
  3. On every relevant request — admin page load, scheduled check — your plugin treats the cached status == "valid" as the gate for premium features.
  4. On a schedule (daily is plenty), your plugin calls GET /licenses/{key}/updates. If hasUpdate is true, it surfaces an update prompt.
  5. When the customer updates, your plugin calls GET /licenses/{key}/download, fetches the signed URL, and installs the package.
  6. If the customer deactivates the plugin or migrates the site, your plugin calls DELETE /licenses/{key}/domains/{domain} to free the seat.

Every step is covered in detail in the pages that follow. Start with Authentication to get your key, then run through the Quickstart to gate a plugin in five minutes.