Non-WordPress Integration
LicenceForge's REST API can be consumed by any HTTP client. This page covers raw HTTP integration for applications that do not run on WordPress, including cURL, plain PHP, and other languages.
Note
All endpoints described here are public-facing and documented in Public Endpoints. If your LicenceForge installation has Require API Key enabled (wplf_require_api_key = yes), you must include the X-LicenceForge-Key header in every request.
Authentication
If API key authentication is enabled on the server, include the key as a request header:
X-LicenceForge-Key: lf_pk_your_public_key_here
This header is required on all public endpoints when wplf_require_api_key is set to yes in your LicenceForge settings. If the setting is disabled, the header is ignored and can be omitted.
Validate a licence
POST /wp-json/wplf/v1/licenses/validate
Request body
{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"product_slug": "my-product",
"site_url": "https://example.com"
}
| Field | Type | Required | Description |
|---|---|---|---|
license_key |
string | Yes | The licence key to validate. |
product_slug |
string | Yes | The product slug this licence belongs to. |
site_url |
string | Yes | The URL of the site requesting validation. |
Response (200 OK)
{
"valid": true,
"status": "active",
"expires": "2025-12-31T23:59:59",
"activation_limit": 5,
"activation_count": 1,
"tier": {
"label": "Pro",
"features": [
"premium-support",
"advanced-forms",
"pdf-export"
]
}
}
Activate a licence
POST /wp-json/wplf/v1/licenses/activate
Request body
{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"product_slug": "my-product",
"site_url": "https://example.com"
}
The request body uses the same fields as the validation endpoint. On success, the server registers the site URL as an active activation slot for the licence.
Response (200 OK)
{
"activated": true,
"status": "active",
"activation_count": 2,
"activation_limit": 5
}
Deactivate a licence
POST /wp-json/wplf/v1/licenses/deactivate
Request body
{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"product_slug": "my-product",
"site_url": "https://example.com"
}
On success, the server removes the site URL from the licence's activation list, freeing the slot for use on another site.
Response (200 OK)
{
"deactivated": true,
"activation_count": 1,
"activation_limit": 5
}
Check for updates
GET /wp-json/wplf/v1/updates/check
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
product_slug |
string | Yes | The product slug to check for updates. |
license_key |
string | Yes | The licence key authorising the update check. |
current_version |
string | Yes | The currently installed version (e.g. 2.4.1). |
site_url |
string | Yes | The URL of the site requesting the update. |
Example request URL
https://licences.example.com/wp-json/wplf/v1/updates/check?product_slug=my-product&license_key=XXXX-XXXX-XXXX-XXXX¤t_version=2.4.1&site_url=https://example.com
Response (200 OK) -- update available
{
"update_available": true,
"new_version": "2.5.0",
"package": "https://licences.example.com/wplf/v1/downloads/my-product?token=eyJ0eXAi...",
"package_hash": "sha256:a3f8c2d1e4b5a6f7...",
"changelog": "Added conditional logic builder. Fixed form submission race condition.",
"requires_php": "7.4"
}
Response (200 OK) -- no update
{
"update_available": false,
"current_version": "2.5.0"
}
cURL example
The following cURL command validates a licence. Replace the URL and values with your own.
curl -X POST "https://licences.example.com/wp-json/wplf/v1/licenses/validate" \
-H "Content-Type: application/json" \
-H "X-LicenceForge-Key: lf_pk_your_public_key" \
-d '{
"license_key": "A1B2-C3D4-E5F6-G7H8",
"product_slug": "my-product",
"site_url": "https://example.com"
}'
PHP example (without WordPress)
For PHP applications that do not have WordPress loaded, use file_get_contents() or any HTTP library.
$api_url = 'https://licences.example.com/wp-json/wplf/v1/licenses/validate';
$payload = json_encode( [
'license_key' => 'A1B2-C3D4-E5F6-G7H8',
'product_slug' => 'my-product',
'site_url' => 'https://example.com',
] );
$context = stream_context_create( [
'http' => [
'method' => 'POST',
'header' => implode( "\r\n", [
'Content-Type: application/json',
'X-LicenceForge-Key: lf_pk_your_public_key',
] ),
'content' => $payload,
'timeout' => 15,
],
] );
$response = file_get_contents( $api_url, false, $context );
if ( $response === false ) {
// Handle connection error
die( 'Failed to connect to licence server.' );
}
$data = json_decode( $response, true );
if ( $data['valid'] ) {
echo 'Licence is active. Tier: ' . $data['tier']['label'];
} else {
echo 'Licence is not valid. Status: ' . $data['status'];
}
Error responses
All endpoints return standard HTTP status codes with a JSON error body on failure.
| Code | Meaning | Common cause |
|---|---|---|
400 |
Bad Request | Missing required field (license_key, product_slug, or site_url). |
401 |
Unauthorized | Missing or invalid X-LicenceForge-Key header when API key is required. |
403 |
Forbidden | Licence key is suspended or cancelled. |
404 |
Not Found | Licence key or product slug does not exist. |
409 |
Conflict | Activation limit reached (all activation slots in use). |
429 |
Too Many Requests | Rate limit exceeded. See Rate Limiting. |
Error response body
{
"code": "license_not_found",
"message": "No licence was found matching the provided key and product.",
"status": 404
}
Future packages
Note
Official Composer and NPM packages for LicenceForge client integration are under consideration for a future release. These packages would wrap the HTTP endpoints described above and provide idiomatic interfaces for PHP (non-WordPress) and Node.js applications. For now, use the raw HTTP endpoints directly.
Next steps
- Public Endpoints -- Full reference for all public API endpoints
- Rate Limiting -- Understand request limits and throttling
- API Key Management -- Creating and managing API keys
- WordPress Integration (3-Class) -- If your application runs on WordPress