Domain-Based Software Licensing: Why It Matters and How It Works
If you sell WordPress plugins, SaaS white-label products, or any web-deployable software, you have a specific problem: a customer buys one license and deploys it across 15 domains.
Domain-based licensing solves this. Instead of just checking "is this key valid?", you check "is this key valid for this domain?"
The Revenue Leak
Consider a WordPress plugin priced at $49/year per site. Without domain binding:
- Customer buys 1 license → $49 revenue
- Customer deploys on 10 client sites → $49 revenue (should be $490)
- Revenue leak: 90%
This isn't theoretical. WordPress plugin developers consistently report that 60-80% of their active installations run on unauthorized domains.
Validate your first license key in under 5 minutes — free plan, no credit card required.
How Domain-Based Licensing Works
The Validation Request
When your application starts (or periodically), it sends a validation request that includes the current domain:
POST /api/v1/licenses/validate
Content-Type: application/json
{ "key": "LIC-XXXX-XXXX-XXXX", "domain": "customer-website.com" } ```
The Validation Response
The API checks three things:
- Is the key valid and active?
- Is this domain authorized for this key?
- Has the domain limit been reached?
{
"valid": true,
"key": "LIC-XXXX-XXXX-XXXX",
"domain": "customer-website.com",
"domains_used": 2,
"domains_allowed": 3,
"plan": "professional",
"expires_at": "2027-04-06T00:00:00Z"
}
If the domain isn't authorized and the limit is reached, validation fails:
{
"valid": false,
"error": "DOMAIN_LIMIT_EXCEEDED",
"domains_used": 3,
"domains_allowed": 3
}
Domain Management
Customers can manage their authorized domains through the portal or API:
- Add a domain — Activate the license on a new site
- Remove a domain — Free up a slot for a different site
- Transfer — Move a license from one domain to another
This gives customers control without requiring support tickets.
Implementation Patterns
WordPress Plugin
<?php
// In your WordPress plugin's main file
function my_plugin_validate_license() { $license_key = get_option('my_plugin_license_key'); $domain = $_SERVER['HTTP_HOST']; $response = wp_remote_post('https://api.trafficorchestrator.com/api/v1/licenses/validate', [ 'headers' => [ 'Authorization' => 'Bearer ' . MY_PLUGIN_API_KEY, 'Content-Type' => 'application/json', ], 'body' => json_encode([ 'key' => $license_key, 'domain' => $domain, ]), ]); if (is_wp_error($response)) { // Network error — use cached result return get_transient('my_plugin_license_valid'); } $body = json_decode(wp_remote_retrieve_body($response)); // Cache for 24 hours set_transient('my_plugin_license_valid', $body->valid, DAY_IN_SECONDS); return $body->valid; }
// Check on admin pages add_action('admin_init', function() { if (!my_plugin_validate_license()) { add_action('admin_notices', function() { echo '<div class="error"><p>License invalid for this domain. Please activate your license in Settings.</p></div>'; }); } }); ```
Node.js SaaS Application
import { TrafficOrchestrator } from '@traffic-orchestrator/client'
const client = new TrafficOrchestrator('your-api-key')
// Middleware for Express/Fastify const validateLicense = async (req, res, next) => { const host = req.hostname const licenseKey = process.env.LICENSE_KEY try { const result = await client.licenses.validate(licenseKey, host) if (!result.valid) { return res.status(403).json({ error: 'License not valid for this domain' }) } next() } catch (error) { // Fail open or closed based on your preference next() // Fail open } } ```
Pricing Strategies with Domain Licensing
Domain-based licensing enables tiered pricing that aligns with customer value:
| Tier | Sites | Price | Target |
|---|---|---|---|
| Personal | 1 site | $49/yr | Bloggers, personal projects |
| Business | 5 sites | $149/yr | Freelancers, small agencies |
| Agency | 25 sites | $399/yr | Web agencies |
| Unlimited | ∞ sites | $999/yr | Enterprise, large agencies |
This pricing model is proven across the WordPress ecosystem. Customers self-select the tier that matches their usage.
Security Considerations
Subdomain Handling
Decide your policy: does app.example.com count as the same domain as example.com? Traffic Orchestrator lets you configure this per license.
Domain Spoofing
Client-side domain checks can be spoofed. For critical applications:
- Validate server-side, not client-side
- Use the Referer/Origin headers as secondary signals
- Combine domain binding with device fingerprinting for desktop apps
Grace Periods
Don't break your customer's production site immediately if validation fails. Implement a grace period:
- Soft failure: Show admin warnings for 7 days
- Hard failure: Disable premium features after 14 days
- Complete lockout: Only after 30 days and multiple failed validations
Getting Started
- Sign up — Free Builder plan includes domain binding
- Create a license with a domain limit
- Integrate validation using any SDK (Node.js, Python, or REST API)
- Add domain management to your customer portal
The entire integration takes 30-60 minutes for most applications.
Published by Traffic Orchestrator Team
Related Articles
- Looking for a Keygen Alternative?
- How to Build a Secure License Key Generator
- Offline License Validation Guide
Ship licensing in your next release
5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.