How Craft License Enforcement Works

This article does not cover the legalities of Craft’s license; only the technical features we’ve put in place to go along with it.

License Key Creation #

The act of downloading Craft binds you to Craft’s License Agreement, but a license key is not assigned to your installation until Craft and it has made its first call to our web services to check for updates. When we see a request without a license key, one is created and sent with the response. Craft saves this new key to config/license.key.

Single Website Enforcement #

You’re allowed to run a single Craft license on multiple domains (e.g., and, so long as they’re all a part of the same installation. To enforce this, Craft does have one technical limitation: you may only access Craft’s control panel from a single public domain per Craft license.

Each time Craft’s control panel sends a request to our web services, it reports the domain it is being accessed from. The first time a key is used on a public domain, we tie it to that domain. This can happen as early as the same request where the license key gets created, if you’re installing Craft on a public server with the web GUI. On subsequent requests, we compare the reported domain with the domain on record.

If a Craft license is used on a public domain other than it was last associated with, our web service reports that there is a mismatch in its response, which Craft surfaces in the control panel.

Craft license mismatch

Licenses can be associated with a new domain via Craft Console.

Edition Enforcement #

Each time Craft phones home, we reconcile the information it sends with our records. The response includes:

  • Licensed Craft and plugin editions;
  • Whether trials are allowed;
  • The domain currently attached to the license;

Craft caches this info, and—if it detects a discrepancy—displays a modal window to administrators with options for correcting the situation. In broad terms, a “discrepancy” is reported when we determine that trials are not allowed in a given environment and there is a mismatch between the licensed and installed editions of Craft or plugins, or when those liceses are already tied to a different domain. Common examples of underlying licensing issues are:

  • Not having purchased one or more licenses for a project that just went live;
  • An invalid license key (either malformed, or not known to our services) being deployed with a project;
  • A site being moved to a new domain;
  • Accessing the control panel from multiple domains;
  • Upgrading Craft or a plugin to a new (unlicensed) edition in a development environment, then deploying;
  • Updating Craft or a plugin to a later version than is allowed by its license;

Notices #

Craft handles licensing issues in a few different ways, depending on the environment.

License issues will only be displayed in the control panel. Craft will never automatically adjust its edition in the event of a discrepancy, and the front-end of your website will never be affected. Depending on the features you use, manually changing the installed edition of Craft (or a plugin) to align with a license may require updates to your site’s code.

Any time there is a discrepancy between installed and licensed editions of Craft or a plugin, the control panel will display a summary at the bottom of every screen, and provide a link that populates a cart on Craft Console with the relevant licenses.

This is the only way license issues are communicated in environments that allow trials.

Craft licensing nudge

A project that displays this notice in a development environment is likely to trigger more conspicuous notices when deployed to a public domain.

Craft license required

When an admin logs in to the control panel, they will see an interstitial screen explaining any outstanding license issues. The Resolve Now link behaves identically to the Buy now link available in the footer.

The reminder can be dismissed for 24 hours, but the wait time will increase gradually as it is shunned. When dismissed, Craft continues to display an alert at the top of all control panel screens:

Craft license reminder

After purchasing the required licenses, return to the control panel and click Refresh on this banner (or the modal).


When does Craft phone home? #

Craft communicates with our web services under a well-defined set of circumstances:

  • Whenever it checks for updates (via the CP or CLI, using php craft update);
  • Whenever someone visits the SettingsPlugins screen with devMode on;
  • Whenever someone visits the in-app Plugin Store;
  • Whenever someone explicitly presses the Refresh button on a Licensing Issues screen;

Users accessing your site’s front-end will never result in communication with our web services.

What information does Craft send to our web services? #

Under the above circumstances, Craft will send these pieces of information:

  • The current environment (determined by Craft::$app->env, which typically comes from a CRAFT_ENVIRONMENT variable);
  • Craft’s installed version and edition;
  • PHP’s version, as well as the installed extensions;
  • Database driver and version;
  • Hostname the site was accessed from, and the requester’s IP (omitted when using the CLI, or if the IP appears to be private or reserved);
  • The current user’s email address (except for console requests);
  • Craft’s license key (either the contents of config/license.key, or the CRAFT_LICENSE_KEY constant);
  • Plugin license keys;
  • The Craft Cloud project ID (if running on our infrastructure);

How do we determine Craft is running on a “public domain?” #

Craft includes the hostname the control panel is being accessed from, when querying our web services. If none of the following criteria are met, we consider the domain to be public:

  1. Does it only consist of only one segment (i.e: localhost)?
  2. Is it an IP address?
  3. Does it include a port number, and is it something other than the normal HTTP ports (80 or 443)?
  4. Does it have a dev-sounding subdomain?
    Exhaustively: acc, acceptance, ci, craftdemo, dev, integration, loc, local, preprod, preview, qa, sandbox, sit, stage, staging, stg, systest, test, testing, and uat.
  5. Does it have a non-standard TLD?
  6. Is it on our list of known development domains? (i.e:,,,, etc.)

The distinction between public and private domains primarily determines which environments trials are allowed in—or more concretely, which environments are not impacted by mismatches in installed and licensed versions.

Do you operate a platform or agency that provides private preview domains? Let us know—we add exemptions on a case-by-case basis.

Applies to Craft CMS 5, Craft CMS 4, Craft CMS 3, Craft Commerce 4, and Craft Commerce 3.