cPanel API Tokens: Automate Backups & Email Accounts Safely
If you've ever written a script that logs into cPanel with your account password to create an email box or kick off a backup, you've been doing it the hard way - and the risky way. cPanel API Tokens let you automate this stuff without ever putting your real password in a script or a cron job. Here's how they work, how to set one up, and where people usually trip over the permissions.
Why Not Just Use Your Password?
Plenty of small scripts out there still authenticate to cPanel's API using Basic Auth with the account's actual username and password. It works, but it means that password is sitting in plaintext somewhere - a cron script, a CI secret, a config file someone forgot to .gitignore. If that script ever leaks, whoever finds it now has full control of your hosting account: files, databases, email, everything.
An API token fixes that. It authenticates as you, but it's a separate credential you can revoke instantly without touching your login password, and - this is the part people miss - you can scope it down to only the things it actually needs to do.
Creating a Token in cPanel
This lives in cPanel itself, not WHM, so any shared or reseller hosting account can use it:
- Log in to cPanel.
- Search for Manage API Tokens in the top search bar (under Security).
- Click Create.
- Give it a name you'll recognize later - something like
backup-script-prod, nottoken1. - Set an expiration date. Don't leave this blank unless you have a real reason to - more on that below.
- Under ACL Privileges, either grant all privileges or pick specific ones (Email, Backup, MySQL, DNS, etc.) depending on what the script needs.
- Click Create, and copy the token immediately.
That last point matters: cPanel shows you the full token value exactly once, right after creation. Close that dialog without saving it and you'll have to delete the token and generate a new one - there's no way to view it again later.
Scoping It Down (the Step People Skip)
By default cPanel offers an all-privileges option, and it's tempting to just tick that and move on. Don't, unless the script genuinely needs full account access. If you're writing a script that only creates email accounts, restrict the token to the Email module. If it only triggers backups, restrict it to Backup. A leaked scoped token is an inconvenience; a leaked all-privileges token is an incident.
If your host account is on WHM as a reseller or you have root, the equivalent lives in WHM > Development > Manage API Tokens, and the ACL list there is more granular still - you can limit a token to specific WHM functions like createacct or list_accounts rather than handing out root-equivalent access for a script that just needs to check disk usage.
Using the Token to Call the API
cPanel's UAPI and the older API 2/API 1 all accept the token the same way - as an Authorization header, no session cookies or password required:
curl -k -H "Authorization: cpanel yourusername:YOUR_TOKEN_HERE" \
"https://yourserver.example.com:2083/execute/Email/list_pops"
Notice the format: cpanel, then your cPanel username, a colon, then the token - not a Bearer token, despite what you might expect from other APIs. For WHM-level calls, the header format is slightly different:
curl -k -H "Authorization: whm root:YOUR_WHM_TOKEN" \
"https://yourserver.example.com:2087/json-api/listaccts"
A quick, safe way to create an email account via UAPI, for example:
curl -k -H "Authorization: cpanel yourusername:YOUR_TOKEN" \
"https://yourserver.example.com:2083/execute/Email/add_pop?email=support&domain=yourdomain.com&password=STRONG_PASSWORD_HERE"a=1024"
Run that from a deployment script and you've replaced a manual cPanel click-through with one line, no password in sight.
Common Problems
| Symptom | Likely Cause | Fix |
|---|---|---|
401 Unauthorized on every call | Wrong header format, or token pasted with a trailing space/newline | Double-check cpanel username:token exactly, and re-copy the token value into your script |
| Works locally, fails in cron | Token stored in an env var that cron's minimal shell doesn't load | Source the env file explicitly in the cron command, or hardcode the token path in the script's config |
Insufficient privileges error on a valid call | Token was scoped to the wrong ACL, or the account itself lacks that feature in its package | Edit the token's ACL in Manage API Tokens, or check the hosting package's feature list |
| Token stopped working overnight | Expiration date was set and has passed | Generate a new token - expired tokens can't be renewed, only replaced |
| Can't find token again to copy | Token value is only ever shown once, at creation | Delete the old token entry and create a fresh one |
Should You Set an Expiration?
Yes, almost always. It's tempting to set a token to never expire for a script you expect to run for years, but an expiring token forces you to actually revisit the automation periodically - which is exactly when you notice the script has been running against a deprecated endpoint, or that nobody remembers what it's for anymore. If you do need a long-lived token for something like a nightly off-site backup job, set a generous expiration (a year, say) and put a calendar reminder to rotate it, rather than leaving it open-ended.
Prevention Checklist
- Never hardcode a token directly in a script that gets committed to version control - use an environment variable or a separate config file outside the repo.
- Scope every token to the minimum ACL it needs, not all-privileges.
- Name tokens descriptively so a year from now you know which script owns which token.
- Set expirations, and keep a simple list of what's due for rotation.
- Delete tokens for scripts that are no longer in use - an orphaned token is a live credential nobody's watching.
- If a token ever ends up somewhere it shouldn't (a public repo, a shared screenshot), delete it in Manage API Tokens immediately and issue a new one - don't wait to see if it gets misused.
Once you've got one automation running on a token instead of a stored password, it's worth going back and doing the same for any other script touching your cPanel account. It's a small change that removes a surprisingly common way hosting accounts get compromised.
Frequently asked questions
Do cPanel API tokens work the same as WHM API tokens?
They're similar in concept but separate systems. A cPanel-level token (created in Manage API Tokens inside cPanel) authenticates as that one cPanel user and is scoped to cPanel/UAPI functions. A WHM-level token (created in WHM's Manage API Tokens) can act with root or reseller privileges and covers WHM functions like account creation across the whole server. Use the one that matches where the automation needs to run.
Can I use an API token instead of my password to log into cPanel's web interface?
No. Tokens are for API calls only - UAPI, API 1/2, or WHM's API. The cPanel and WHM login pages still require your actual account password (and 2FA, if enabled). Tokens can't be used to authenticate a browser session.
What happens if I lose or forget to copy a token after creating it?
There's no way to retrieve the value again - cPanel only displays it once, at creation. Go back to Manage API Tokens, delete that entry, and create a new one. This is also why it's worth pasting the token straight into your script or secrets manager immediately rather than a temporary note.
Is it safe to give a token all privileges if the server isn't shared with anyone else?
It's safer than nothing, but still not best practice. Scoping matters because it limits the blast radius if the token leaks through a misconfigured log, an accidental commit, or a compromised machine running the script - not because you don't trust the account owner.
Can I automate backups on Getwebup hosting using an API token?
Yes - scope a token to the Backup ACL in cPanel's Manage API Tokens, then call the relevant UAPI Backup functions (like requesting a full or partial backup) from a cron job or external script using the Authorization header shown above.