Adding license validation to your software shouldn't require a PhD in cryptography. Here's how to do it in 10 lines (or less) across popular languages.
The API
Every example below calls the same REST endpoint:
POST /api/v1/license/validate
Content-Type: application/json
{
"license_key": "your-key",
"domain": "customer-domain.com"
}
Response:
{
"valid": true,
"plan": "professional",
"features": { "max_domains": 10, "api_calls": 50000 }
}
Now let's implement it everywhere.
JavaScript / Node.js
const validateLicense = async (key, domain) => {
const res = await fetch('https://api.trafficorchestrator.com/api/v1/license/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ license_key: key, domain })
});
return res.json();
};
Python
import requests
def validate_license(key, domain):
r = requests.post('https://api.trafficorchestrator.com/api/v1/license/validate',
json={'license_key': key, 'domain': domain})
return r.json()
Go
func validateLicense(key, domain string) (map[string]interface{}, error) {
body, _ := json.Marshal(map[string]string{"license_key": key, "domain": domain})
resp, err := http.Post("https://api.trafficorchestrator.com/api/v1/license/validate",
"application/json", bytes.NewBuffer(body))
if err != nil { return nil, err }
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}
Ruby
require 'net/http'
require 'json'
def validate_license(key, domain)
uri = URI('https://api.trafficorchestrator.com/api/v1/license/validate')
res = Net::HTTP.post(uri, { license_key: key, domain: domain }.to_json,
'Content-Type' => 'application/json')
JSON.parse(res.body)
end
PHP
function validate_license($key, $domain) {
$response = wp_remote_post('https://api.trafficorchestrator.com/api/v1/license/validate', [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode(['license_key' => $key, 'domain' => $domain])
]);
return json_decode(wp_remote_retrieve_body($response), true);
}
cURL (Bash)
curl -X POST https://api.trafficorchestrator.com/api/v1/license/validate \
-H "Content-Type: application/json" \
-d '{"license_key":"your-key","domain":"example.com"}'
Rust
async fn validate_license(key: &str, domain: &str) -> Result<serde_json::Value, reqwest::Error> {
let client = reqwest::Client::new();
let body = serde_json::json!({"license_key": key, "domain": domain});
let res = client.post("https://api.trafficorchestrator.com/api/v1/license/validate")
.json(&body).send().await?.json().await?;
Ok(res)
}
C# / .NET
async Task<JsonElement> ValidateLicense(string key, string domain) {
var client = new HttpClient();
var content = new StringContent(
JsonSerializer.Serialize(new { license_key = key, domain }),
Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.trafficorchestrator.com/api/v1/license/validate", content);
return JsonSerializer.Deserialize<JsonElement>(await response.Content.ReadAsStringAsync());
}
What You Get Back
Every successful validation returns:
| Field | Type | Description |
|---|---|---|
valid |
boolean | Whether the license is valid for this domain |
plan |
string | The plan tier (builder, starter, professional, business, enterprise) |
features |
object | Plan-specific feature limits |
expires_at |
string | When the license expires (ISO 8601) |
Error Handling
Always handle failures gracefully:
const result = await validateLicense(key, domain);
if (!result.valid) {
// Show upgrade prompt, not a hard block
showUpgradeNotice(result.error);
} else {
enablePremiumFeatures(result.features);
}
Pro tip: Cache validation results locally for 5-15 minutes to reduce API calls and handle temporary network issues.
Traffic Orchestrator provides SDKs for all these languages (and more) with built-in caching, retry logic, and offline fallback. Get started free.
Top comments (0)