Using the WMD SED API from a PHP Script
This article describes the Bearer token method available in WMD SED version 6.1 and later (released mid-April 2026). If you are running an older version, please update to use this method. For older installations, refer to the legacy session ID approach or use the statefull REST API.
The WMD SED API is session-based and designed primarily for browser-based tools that share the active session cookie. For PHP scripts running outside the browser, such as server-side automation, scheduled tasks, or remote integrations, a different approach is needed.

The solution is api-sl.php (Secure Layer), a companion entry point to api.php that accepts an encrypted Bearer token in the Authorization header. This allows any PHP script to authenticate and make API calls without needing access to the browser session cookie, and without passing session IDs as plain URL parameters.
Unlike simpler approaches, this method is not restricted to intranet use. The calling script can run from any location that can reach your WMD SED installation over HTTPS, including remote servers, local development machines, or scheduled tasks.
How it Works
WMD SED already returns an encrypted etoken in the c=auth response. This token is an AES-256-CBC encrypted and HMAC-SHA3-512 signed value that WMD SED assembles at login as:
salt ; session_id ; unix_timestamp ; server_ip
The api-sl.php entry point decrypts this token, extracts the session ID, and injects it before the WMD loader starts the session. From that point on, WMD SED handles the request exactly as it would any authenticated session.
The authentication flow is:
- Your script calls
c=authwith username and password credentials - WMD SED authenticates the user and returns an encrypted
etoken - Your script passes the
etokenas a Bearer token in theAuthorizationheader on all subsequent requests toapi-sl.php api-sl.phpdecrypts the token, validates it, and injects the session ID before the WMD loader starts the session- WMD SED handles the request normally under that authenticated session
Security
The security of this mechanism has two layers:
- Encryption: The token is encrypted with a fixed internal WMD SED key. This is not a secret (it is the same across all installations) but it prevents casual inspection of the token contents.
- HMAC verification: The token is signed using
$db_config_publickey, a random key that is automatically generated by the WMD SED download script and is unique to each installation. It is never shared and cannot be derived from any public information. A token generated by one WMD SED installation will fail HMAC verification on any other installation, making cross-installation replay attacks impossible.
The token also carries a timestamp and is only valid for a short window after it is issued, providing built-in anti-replay protection.
Setting Up api-sl.php
From version 6.x (mid-April 2026 onwards), api-sl.php is included in the root installation folder alongside api.php.
Important: api-sl.php is a companion file and does not replace api.php. Do NOT modify the original api.php.
Sample Script
The following is the complete api-test-with-token.php sample script showing the full authenticate > query > display cycle:
<?php
###############################################################################
/**
* api-test-with-token.php - Sample code demonstrating how to use the WMD SED API
* with Bearer token authentication via api-sl.php.
*
* This script shows the full authenticate -> query -> display cycle.
* It can be run from the command line or from a browser.
*
* Usage:
* 1. Set WMD_API_URL below to point to your api-sl.php installation
* 2. Set WMD_API_USER and WMD_API_PASS to your WMD SED credentials
* 3. Run from CLI: php api-test-with-token.php
* Or place on a web server and open in a browser
*
* Authentication flow:
* 1. authenticate() calls c=auth with user/pass credentials
* 2. WMD SED returns an encrypted etoken on success
* 3. The etoken is passed as a Bearer token in the Authorization header
* on all subsequent requests to api-sl.php
* 4. api-sl.php decrypts the token, extracts the session ID, and injects
* it before the WMD loader starts the session
*
* @author Anil Kumar <akumar@codepunch.com>
* @link https://codepunch.com
*
*/
###############################################################################
// WMD SED installation URL. Point this to your api-sl.php location.
// Must be HTTPS in production.
define('WMD_API_URL', 'https://your-wmdsed-installation.example.com/api-sl.php');
// WMD SED login credentials. Replace with your own.
define('WMD_API_USER', 'your-username');
define('WMD_API_PASS', 'your-password');
// In production, never hardcode credentials here. Instead, consider:
// - Reading from a config file outside the web root:
// $cfg = parse_ini_file('/etc/wmdsed/credentials.ini');
// define('WMD_API_USER', $cfg['user']);
// define('WMD_API_PASS', $cfg['pass']);
//
// - Reading from environment variables:
// define('WMD_API_USER', getenv('WMD_USER'));
// define('WMD_API_PASS', getenv('WMD_PASS'));
//
// - Prompting interactively when running from CLI:
// define('WMD_API_USER', readline('Username: '));
// define('WMD_API_PASS', readline('Password: '));
###############################################################################
/**
* Returns the base API URL with a leading query separator.
* All API calls append their parameters to this URL.
*
* @return string
*/
function get_url() {
return WMD_API_URL . '?';
}
###############################################################################
/**
* Detects whether the script is running from the command line.
* Used by smart_echo() and show() to switch between plain text
* and HTML output.
*
* @return bool
*/
function is_cli() {
return PHP_SAPI === 'cli';
}
###############################################################################
/**
* Outputs a scalar value, switching between plain text and HTML
* depending on whether the script is running in CLI or browser mode.
*
* @param mixed $msg The value to display
* @param string $prompt Optional label prepended to the output
*/
function smart_echo($msg, $prompt="") {
if($prompt != "")
$msg = "$prompt: $msg";
if($msg === false)
$msg = "False";
else if($msg === true)
$msg = "True";
if(is_cli()) {
$msg = html_entity_decode($msg);
echo strip_tags($msg) . "\n";
}
else {
if($msg == strip_tags($msg) && strpos($msg, "\n") !== false)
echo "<pre>$msg</pre>";
else
echo "<p>$msg</p>";
}
}
###############################################################################
/**
* Outputs any value - scalar, array, or object - in a readable format.
* Arrays and objects are passed through print_r(), wrapped in <pre> tags
* in browser mode. Scalars are passed to smart_echo().
*
* @param mixed $pdata The value to display
*/
function show($pdata) {
if(is_array($pdata) || is_object($pdata)) {
if(!is_cli())
echo "<pre>";
print_r($pdata);
if(!is_cli())
echo "</pre>";
}
else
smart_echo($pdata);
}
###############################################################################
/**
* Makes a GET request to a URL using cURL, optionally passing a Bearer token
* in the Authorization header and a custom User-Agent string.
*
* Returns an array with:
* 'result' => raw response body (empty string on failure)
* 'status' => HTTP status code
* 'error' => cURL error string (only present if an error occurred)
*
* SSL verification is enabled. Ensure your server has a valid certificate.
*
* @param string $url URL to request
* @param string|false $accesstoken Bearer token, or false for unauthenticated requests
* @param string|false $useragent Custom User-Agent string, or false to omit.
* Pass '?' or '-' to use a generic browser UA.
* @param int $timeout Request timeout in seconds
* @return array
*/
function curl_get_url($url, $accesstoken=false, $useragent=false, $timeout=10) {
$retv = array('result' => "", 'status' => 0);
if(function_exists('curl_version')) {
$httpheader = false;
if($accesstoken !== false && $accesstoken != null) {
$httpheader = array(
"Authorization: Bearer $accesstoken",
);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
if($httpheader !== false)
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
if($useragent !== false && $useragent != "") {
if($useragent == "?" || $useragent == "-")
$useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13';
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
}
$retv['result'] = curl_exec($ch);
$retv['result'] = ($retv['result'] === false) ? "" : $retv['result'];
$retv['status'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(curl_error($ch))
$retv['error'] = curl_error($ch);
curl_close($ch);
}
return $retv;
}
###############################################################################
/**
* Authenticates against the WMD SED API using username and password.
*
* On success, stores the returned etoken in the global $seid for use
* as a Bearer token on all subsequent API calls.
*
* Note: $seid is a global here for simplicity in sample code. In production
* code, pass the token explicitly rather than relying on global state.
*
* @param string $user WMD SED username
* @param string $pass WMD SED password
* @return array Raw cURL response array
*/
function authenticate($user, $pass) {
$turl = get_url() . http_build_query(['c' => 'auth', 'user' => $user, 'pass' => $pass]);
show($turl);
$data = curl_get_url($turl);
$result = json_decode($data['result'], true);
show($result);
if($result['status'] == 'ok') {
global $seid;
$seid = $result['etoken'];
}
return $data;
}
###############################################################################
/**
* Fetches a page of domain records from the WMD SED domain grid.
* Demonstrates a standard authenticated grid query.
*
* @return array Raw cURL response array
*/
function get_domain_grid() {
global $seid;
$turl = get_url() . http_build_query([
'c' => 'grid',
't' => 'domain',
'columns' => 'sid,domain,registry_expiry,registrar_expiry,ip,ns1',
]);
show($turl);
return curl_get_url($turl, $seid);
}
###############################################################################
/**
* Fetches the user list from the WMD SED admin endpoint.
* Demonstrates an authenticated admin query.
* Note: Requires the authenticated user to have administrator rights.
*
* @return array Raw cURL response array
*/
function get_user_list() {
global $seid;
$turl = get_url() . http_build_query([
'c' => 'admin',
't' => 'users',
'oper' => 'list',
]);
show($turl);
return curl_get_url($turl, $seid);
}
###############################################################################
// Authenticate and run sample queries
// Replace WMD_API_USER and WMD_API_PASS at the top of this file
// with your own credentials before running.
###############################################################################
$seid = null;
$data = authenticate(WMD_API_USER, WMD_API_PASS);
show($data);
$data = get_domain_grid();
show($data);
$data = get_user_list();
show($data);
###############################################################################