Every request to the reseller API sends two headers:
username — the reseller client’s WHMCS email (your API Email Address from Settings → API Details).
token — a signed value derived from your API key that rotates every UTC hour.
You never send the API key itself. Instead you send a token computed from it.
The token is an HMAC-SHA256 signature, hex-encoded, then base64-encoded. In PHP:
Read this carefully — the arguments are not where you might expect:
- The algorithm is HMAC-SHA256.
- The message being signed is your API key.
- The key is the string
"<email>:<timestamp>", where the timestamp is the current UTC time formatted as yy-mm-dd HH (two-digit year, two-digit month and day, hour 00–23).
hash_hmac(..., $binary = false) returns a lowercase hex string. That hex string is then base64-encoded to produce the final token.
Because the timestamp only includes the hour, a token is valid for the current UTC hour. Compute a fresh token per request, or at least once per hour.
Keep your API key secret. Store it in an environment variable or secrets manager, never in client-side code or version control. Add your server IPs to the Allowed IP Addresses allowlist in Settings → API Details so only your infrastructure can call the API.
Clock skew
Because the timestamp resolves to the hour, small clock differences are usually fine. But near the top of the hour, a server whose clock is a minute fast or slow can compute a token for the wrong hour and get rejected. Keep your server clock synced with NTP. If a call fails right around an hour boundary, retry — the next attempt will fall inside the correct hour.
Cloudflare and the User-Agent
The endpoint sits behind Cloudflare. Requests sent with a default scripting User-Agent (for example Python-urllib) can be blocked with 403 error code: 1010. Send a normal User-Agent. The snippets below all use clients that pass an acceptable User-Agent by default.
Make an authenticated call
Each snippet computes the token and calls GET /version, which returns the API version string. All five were validated live against the sandbox and returned "2.3.0". Replace your-api-key and [email protected] with your own credentials.
Response:
Reuse this token computation for every endpoint. The rest of the reference shows only the action path and parameters for each call.