HMAC authentication signs each request using an API key identifier and its signing secret. Use this method for an application issued an HMAC credential, including the supported Blesta and FOSSBilling workflows. It is separate from the email/API-key method used by the current WHMCS connector.
IN THIS ARTICLE
01 Prepare the credential
Create a permitted API application and key through the advanced API workflow. Save the signing secret when it is revealed. Configure only the scopes and source networks the application needs, and ensure the sending server's clock is accurate.
Send X-Auth-Key, X-Auth-Timestamp, X-Auth-Nonce and X-Auth-Signature. The timestamp is Unix time in seconds. A nonce must be a fresh 16 to 160 character value using letters, digits, underscore or hyphen. The default accepted clock difference is five minutes, subject to the installed configuration.
02 Build the canonical string
Join these six values with newline characters and no extra trailing line:
UPPERCASE_HTTP_METHOD
/v2/route/path
SORTED_QUERY_STRING
LOWERCASE_SHA256_HEX_OF_RAW_BODY
UNIX_TIMESTAMP
UNIQUE_NONCE
The signed path is the v2 route, such as /v2/profile, after the API script prefix has been removed. It is not the full HTTPS URL. Sort associative query keys recursively, preserve list order and encode with RFC 3986 query encoding. For an empty query, retain an empty third line.
Hash the exact bytes that will be sent as the request body. A GET without a body hashes the empty string. For JSON, serialize once, sign that string and send it unchanged. Reformatting whitespace or reordering JSON after signing changes the body hash.
$canonical = implode("\n", [$method, $path, $query, hash('sha256', $body), $timestamp, $nonce]);
$signature = base64_encode(hash_hmac('sha256', $canonical, $secret, true));
The binary-output flag in the HMAC call matters. Base64 encodes the raw digest, not its hexadecimal text.
03 Send and verify
Append the route to our current API base and keep TLS verification enabled. Do not include email/API-key headers with HMAC headers. For routes that require idempotency, send the business request's Idempotency-Key as well.
Begin with a read request such as profile or capabilities. An authentication failure can identify a missing header, expired or inactive key, wrong signature, clock problem or source-network restriction. Compare the canonical values locally without logging the secret.
How do I sign a retry without reusing an authentication nonce?
Every transport attempt needs a fresh nonce and current timestamp with a new signature. For an unchanged business mutation, retain the original idempotency key and identical method, path, query and body. Reusing the nonce is a replay, while replacing the idempotency key may represent another paid request.