Skip to content
Shahid Malla

WHMCS API Guide: How Do You Authenticate and Make API Calls?

A checked guide to the WHMCS API: API roles and credentials, the IP allow-list and access key, a first call to includes/api.php, nine common actions, localAPI, paging, debugging and the risks.

· Published · Updated · 11 min read · 10 steps

To use the WHMCS API from another server, create an API role and an API credential in the admin area, add the caller's IP address to the allowed list, then send an HTTPS POST to includes/api.php with the identifier, the secret, an action name and responsetype=json. Code that runs inside WHMCS calls the localAPI() function instead, without an identifier or secret.

I checked every action name, parameter and menu path below against the official WHMCS documentation on 28 October 2026. This guide covers calling WHMCS. Reacting to events inside WHMCS is a different job, covered in my WHMCS hooks guide.

What is the WHMCS API, and which form do you need?

The WHMCS API is a set of named actions, such as AddClient or GetInvoices, that let code do what staff do in the admin area. The API index listed 162 actions when I counted them again on 28 October 2026, the same number as at my last review, grouped under headings such as Orders, Billing, Client, Support, Service and Domains. There are two ways to reach them.

  • External API. For a system hosted somewhere else: a marketing site, a mobile app backend, an accounting tool. It accepts POST requests at https://your-whmcs-url/includes/api.php.
  • Internal API. For code inside the WHMCS installation: hooks, modules and custom pages. It is one PHP function, localAPI().

Both run the same actions with the same parameters, so the reference page for an action serves both.

Four steps to a first WHMCS API call: create an API role with only the actions needed, generate an identifier and secret for an admin with API Access, add your server's IP under API IP Access Restriction, then POST to includes/api.php and check that result is success. Notes: without a fixed IP an access key skips the check and must be guarded like a secret; list actions page with limitstart and limitnum, 25 records by default.
Three settings, then the first call; the sections below take each in turn. Source: shahidmalla.com, from the WHMCS developer documentation.

How do you create WHMCS API credentials?

You create them at Configuration > System Settings > Manage API Credentials, and you must create an API role first. The role is the list of actions the credential may run. The steps below follow the API Credentials documentation.

  1. On the API Roles tab, click Create API Role, name it, and tick only the actions this integration needs.
  2. On the API Credentials tab, click Generate New API Credential.
  3. Select the admin user the credential will authenticate as, add a description, and select the role.
  4. Click Generate and copy the identifier and the secret. If you lose the secret, you have to generate a new pair and delete the old one.

Three rules catch people out. The admin user's role group needs the API Access permission. A credential with no role is authorized for nothing. And disabling or deleting the admin user invalidates that user's credentials, while changing the admin's password does not.

The authentication page also describes an older method: an admin username with the MD5 hash of the admin password. It is kept for backwards compatibility and may be deprecated. I do not use it for new work, because it ties an integration to a person's login.

The same page adds a detail worth knowing when you read older sample code: for forwards compatibility, a valid identifier and secret may also be sent in the username and password fields. A script written for the pre-7.2 method therefore keeps working once you swap the two values for a modern credential pair.

How do you allow your server's IP address to use the WHMCS API?

Add the address under API IP Access Restriction on the Security tab at Configuration > System Settings > General Settings. The access control page states that access to the API is restricted by IP by default, so a correct identifier and secret are not enough on their own. That page still gives the old menu path, "Setup > General Settings > Security".

When the caller has no fixed address, WHMCS offers an access key. Add this line to configuration.php in the WHMCS root, then send the same value as an accesskey parameter with every request:

$api_access_key = 'a-long-random-passphrase';

The access control page limits the characters the key may contain: "letters, numbers, and the following special characters only: ! @ # $ % . ( ) * [ ] - _". A generated passphrase that strays outside that set is worth rewriting before you chase a failing call.

The key bypasses the IP restriction, so it removes a layer of protection. Use it only when a fixed address is not possible, and treat it like a second secret.

How do you make a first WHMCS API call?

Send a POST with four fields plus the parameters of the action: identifier, secret, action and responsetype. This PHP example looks up a client by email address.

<?php
$keys = require '/home/acme/whmcs-api-keys.php'; // outside the web root

$ch = curl_init('https://billing.example.com/includes/api.php');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query([
        'identifier'   => $keys['identifier'],
        'secret'       => $keys['secret'],
        'action'       => 'GetClientsDetails',
        'email'        => 'jane@example.com',
        'responsetype' => 'json',
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 30,
]);
$data = json_decode(curl_exec($ch), true);

if (($data['result'] ?? '') !== 'success') {
    throw new RuntimeException($data['message'] ?? 'No valid reply from WHMCS');
}

echo $data['client']['fullname'];

Every response carries a result field that is either success or error, and an error comes with a message such as "Client Not Found". The documentation lists three response types: JSON, which it recommends, XML, and NVP, which is deprecated. For a first test, WhmcsDetails needs no parameters and returns the version of the installation.

One detail in that example is easy to miss. GetClientsDetails still returns the client fields at the top level of the response, but the reference marks that copy as deprecated. Read from the client array.

Which WHMCS API actions are used most?

These nine cover most of the integration work I am asked for. The required parameters are in addition to action.

ActionWhat it doesRequired parametersWorth knowing
WhmcsDetailsReturns the version of the installation.None.A safe first test of credentials and IP access.
AddClientAdds a client.Name, email, address, city, state, postcode, country and phone number, plus password2 when no owner_user_id is sent.Returns clientid. Set noemail to true to skip the welcome email.
GetClientsDetailsReturns one client's details.clientid or email.Add stats for account statistics.
AddOrderAdds an order to a client.clientid and paymentmethod.It ignores the product's "setup as soon as an order is placed" option, so you must call AcceptOrder afterwards.
AcceptOrderAccepts a pending order.orderid.autosetup and sendemail control provisioning and emails.
GetInvoicesLists invoices.None.Filter by userid or status. Returns 25 records unless you set limitnum.
AddInvoicePaymentAdds a payment to an invoice.invoiceid, transid, gateway and date.Leave amount out to pay the full invoice.
ModuleCreateRuns the module create action for a service.serviceid.Siblings: ModuleSuspend, ModuleUnsuspend, ModuleTerminate.
CreateSsoTokenCreates a single-use login token for a client or user.client_id or user_id.Valid for 60 seconds at most. It returns an access_token and a ready-made redirect_url, and destination picks the landing page, such as clientarea:services.

ModuleCreate only tells WHMCS to run the provisioning module assigned to the product. What that module does on the remote system is a separate piece of code, which I cover in my guide to building a WHMCS provisioning module.

How do you call the WHMCS API from inside WHMCS with localAPI?

Call localAPI($command, $values, $adminUsername) and read the returned array. The third argument is an admin username, which the WHMCS troubleshooting page marks as optional.

$result = localAPI('GetClientsDetails', ['clientid' => 42, 'stats' => true]);

if ($result['result'] === 'success') {
    $email = $result['client']['email'];
}

The internal API page says a hook or module does not need to include init.php, because WHMCS is already running. A standalone PHP script in the WHMCS directory does need require_once 'init.php'; first. No HTTP request is involved.

When should you use OAuth instead of API credentials?

Use OAuth when an app acts on behalf of a WHMCS user rather than on behalf of you. An API credential authenticates as an admin, so every call carries that admin's authority no matter who set it off. That is right for your own scripts and wrong for an app your clients install.

The OAuth introduction says WHMCS uses OAuth 2, that the user authenticates with WHMCS to verify their identity and grant the app permission, and that the user may revoke access at any time. The app never stores or transmits the user's WHMCS password. Once the user authorizes it, WHMCS returns an access token that the app sends with each later request, and that token identifies both the app and the end user.

Four actions in the API index manage those app registrations: CreateOAuthCredential, ListOAuthCredentials, UpdateOAuthCredential and DeleteOAuthCredential. For a reporting job or a sync script that you run on your own server, admin API credentials stay the simpler choice, and the rest of this guide applies.

How do you page through WHMCS API results?

List actions such as GetInvoices take limitstart as the offset and limitnum as the page size, and they report totalresults, startnumber and numreturned. The default is 25 records, so a script that reads only the first response silently misses the rest. Loop until startnumber plus numreturned reaches totalresults, and stop the loop on any response whose result is not success.

How do you debug a WHMCS API call that fails?

Read the message field first, then check the three things that sit in front of every action: the role, the IP address and the credential. If that does not explain it, WHMCS has two logging switches.

  • API debug logging. The API troubleshooting page says to add $api_enable_logging = true; to configuration.php. Calls are then written to the tblapilog database table. Remove the line when you finish.
  • Log API Authentication. This setting on the Security tab of General Settings records successful API authentications in the Admin Log at Configuration > System Logs. It is off by default.

Then cut the request down to the documented example for that action and add your parameters back one at a time. AddOrder rewards that patience, because many of its parameters are arrays with one entry per product.

What are the limits and risks of the WHMCS API?

The main risk is that an API credential does whatever its role allows, with no person watching. Plan for these points.

  • Keep roles narrow. A reporting script needs the "Get" actions and nothing else. Give each integration its own credential so you can delete one without breaking the others.
  • Never call the API from browser JavaScript. The identifier and secret would be readable by every visitor. Put a small server-side script between the browser and WHMCS.
  • Treat CreateSsoToken with care. The reference warns that the token gives complete authentication to the client account and that the login it leads to does not enforce captcha or two-factor checks. Verify the person's identity on your side first.
  • Do not write to the WHMCS database when an action exists. A direct insert can skip validation and follow-up steps that the action performs.
  • The API does not notify you. It answers when asked. To be told that an invoice was paid or a client signed up, use a hook.

What else do people ask about the WHMCS API?

Can you use the WHMCS API without an IP allow-list?

Yes, with an access key. Set $api_access_key in configuration.php and send the same value as an accesskey parameter on every request. The access control page limits the key to letters, numbers and the characters ! @ # $ % . ( ) * [ ] - _. Because it bypasses the IP check entirely, keep it to callers that genuinely have no fixed address.

Does changing an admin password break WHMCS API credentials?

No. The API Credentials documentation states that you can alter the admin's password without invalidating API credentials. Disabling or deleting that admin does invalidate them. Worth settling before an integration goes live, because an admin account closed during a staff change takes every integration that authenticates as that person with it.

Can you still authenticate with an admin username and password?

Yes, but treat it as legacy. Before WHMCS 7.2 the API checked admin login credentials, and the authentication page says that method is still supported for backwards compatibility and may be deprecated in a future version. New integrations should use an identifier and secret from Manage API Credentials.

Does localAPI need an admin username?

No, not since WHMCS 7.2. The sample code on the CreateSsoToken reference marks the third argument of localAPI() as optional for WHMCS 7.2 and later. Inherited hooks often still pass a hard-coded admin username, which is one of the first things I check when old custom code stops working after a staff change.

What happens if an action is not in the credential's role?

WHMCS refuses to authorize the request, and the response comes back with result set to error rather than data. The documentation is blunt about the two ways to arrive there: a credential with no assigned role is authorized for nothing, and if roles are assigned but none of them allow any API action, the system denies every request. Check the role before you check your code.

If you would rather have an integration built and tested on a staging copy, that is my WHMCS API integration and automation service, and a review of existing credentials and roles is part of a WHMCS security audit; the scoping call of about 30 minutes is free and a written quote follows within one business day.

Last reviewed 28 October 2026. Disclosure: I am a freelance WHMCS developer and I sell API integration work at $55-$65 per hour or a fixed quote, so I am not neutral. I am CTO at ElySpace, a freelance developer for Marmaids LLC, and founder of WHMCSPilot and MagizAI.

Share this article

Shahid Malla

Written by

Shahid Malla

Freelance WHMCS developer and web designer with 13+ years of client work. CTO at ElySpace, freelance developer for Marmaids LLC, and founder of WHMCSPilot and MagizAI.

Got a project like this?

Tell me what you need and I will send a written quote within one business day.