Create a MySQL database and user on web hosting
6 steps · Checked against the API code 3 November 2026
A guide does one task from start to finish. Every endpoint, with all its fields and cases, is in the API reference.
A website or app on Hostup web hosting keeps its data in a MySQL database. The API cannot create the database itself. You create it in the hosting control panel. Everything around it works through the API: the database user, its access to the database and the places it may connect from.
The AI app cannot give the user access to a database. Do step 5 through the API.
Before you start
Section titled “Before you start”- An API key with the scopes
write:hostingandconsole:services.write:hostingalso coversread:hosting. Keys and scopes - The requests read the key from
$HOSTUP_API_KEY, as set in the Quickstart. - A browser for step 3.
1. Find the web hosting account
Section titled “1. Find the web hosting account”List web hosting accounts with include=domains returns your web hosting accounts and the domains on each.
curl "https://cloud.hostup.se/api/v2/shared-hosting?include=domains" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "data": [ { "id": "acct_01hxa3b4c5d6e7f8g9h0j1k2m3", "primaryDomain": "example.com", "domains": ["example.com"], "serviceStatus": "active", "controlPanel": { "type": "cpanel" }, "…": "…" } ], "hasMore": false, "nextCursor": null}Find the account whose domains has the site the database is for. Pick an account with serviceStatus active and controlPanel.type cpanel. Keep its id:
export ACCOUNT_ID="acct_…" # data[].id of that accountThe list comes 20 per page. When hasMore is true, send nextCursor as cursor for the next page. Pagination
2. Check that the plan has room for a database
Section titled “2. Check that the plan has room for a database”List hosting databases shows the databases on the account and whether the plan allows one more.
curl "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/databases" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "databases": [ { "id": "db_01hxa3b4c5d6e7f8g9h0j1k2m3", "name": "abcde_wp", "…": "…" } ], "quota": { "used": 1, "limit": null, "remaining": null }, "actions": { "canCreate": { "allowed": true, "reason": null } }}When canCreate.allowed is false, reason says why, for example “Databases are not available on your current plan.” quota.limit is the number of databases the plan allows. null means no limit.
3. Create the database in the control panel
Section titled “3. Create the database in the control panel”Create a control panel login link gives you a login to the account’s control panel. The client area opens the same control panel.
curl -X POST "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/actions/sso" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json"{ "loginUrl": "https://server1.example.com/login/session/…", "expiresAt": null, "singleUse": true}Open loginUrl in a browser. It works once. Don’t store it. In the control panel, open MySQL Databases in the Databases section and create the database. Then list the databases again as in step 2. The new database is there with its full name, for example abcde_shop.
When the name starts with a prefix, such as abcde_ in abcde_shop, give the user in step 4 the same prefix. Some servers put the account’s prefix on every database and database user name. The API does not add it for you.
4. Create the database user
Section titled “4. Create the database user”Create database user adds a MySQL user to the account.
curl -X POST "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/database-users" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{"username": "abcde_shopuser", "password": "Amber-Ladder-41-Orchard"}'{ "id": "dbu_01hxa3b4c5d6e7f8g9h0j1k2m3", "username": "abcde_shopuser", "host": null, "databases": []}username: letters, digits and underscores. Any other character returns 400invalid_request. The database server takes at most 32 characters, the prefix included. A longer name fails with 502upstream_failed. A name that already exists fails the same way. List database users shows the names in use.password: 8 to 128 characters with at least one uppercase letter, one lowercase letter and one digit. It must also be hard to guess. A password close to the user name fails withpassword_too_weak. Generate a new one. Never use the one in this example.
The response never repeats the password. Keep it where your app reads it. Keep id too. The calls on this user accept it in place of the user name.
export DB_USER_ID="dbu_…" # id above5. Give the user access to the database
Section titled “5. Give the user access to the database”Grant database privileges links the user to one database. Use the database name from step 3.
curl -X POST "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/database-users/$DB_USER_ID/privileges" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{"database": "abcde_shop", "privileges": ["ALL PRIVILEGES"]}'{ "username": "abcde_shopuser", "database": "abcde_shop", "privileges": ["ALL PRIVILEGES"]}ALL PRIVILEGES gives the user full rights on this one database. For a narrower user, list privileges such as SELECT, INSERT, UPDATE and DELETE. Grant database privileges lists every one.
6. Connect to the database
Section titled “6. Connect to the database”Where your code runs decides what it needs.
From PHP on the same web hosting account
Section titled “From PHP on the same web hosting account”Connect to localhost with the user and password from step 4 and the database name from step 3. PHP (mysqli and PDO) then uses the local socket. The socket is always allowed. Nothing more is needed.
From Node.js or another TCP client on the same account
Section titled “From Node.js or another TCP client on the same account”A client that connects over TCP is seen as 127.0.0.1. When it resolves localhost to IPv6, it is seen as ::1. Those addresses are refused until you allow them. There are two ways:
- Connect through the socket instead:
/var/lib/mysql/mysql.sock. In Node.js mysql2, set it assocketPath. - Allow
127.0.0.1and::1as hosts, as in the next case.localhostitself is refused with 400invalid_request.
From another server or your own computer
Section titled “From another server or your own computer”Put the public IP address of that server or computer on the account’s list of allowed hosts. Allow a database access host adds one.
curl -X POST "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/database-access-hosts" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{"host": "192.0.2.10"}'{ "host": "192.0.2.10", "note": null}host is an IP address, an IP range with % as the wildcard (192.0.2.%), a hostname or % for every host. The list is account-wide. Every database user on the account may connect from every host on it. With %, a password is the only thing that protects the databases. Prefer one address.
Then get the server’s hostname from Get connection details for web hosting.
curl "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/account-details" \ -H "Authorization: Bearer $HOSTUP_API_KEY"{ "id": "acct_01hxa3b4c5d6e7f8g9h0j1k2m3", "access": { "username": "abcde", "serverHostname": "server1.example.com", "…": "…" }, "…": "…"}Connect to access.serverHostname on port 3306 with the user and the password from step 4. Use the hostname, not your domain. The domain may point somewhere else.
mysql -h server1.example.com -P 3306 -u abcde_shopuser -p abcde_shopChange the user later
Section titled “Change the user later”The calls below use $DB_USER_ID from step 4. The user name works in its place too.
Set a new password
Section titled “Set a new password”Send the new password as newPassword. The same rules as in step 4 apply. Apps that still use the old password stop connecting until you update them.
curl -X PUT "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/database-users/$DB_USER_ID/password" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{"newPassword": "Silver-Kettle-29-Harvest"}'{ "username": "abcde_shopuser"}Take its access to a database away
Section titled “Take its access to a database away”Revoke database privileges takes every privilege the user has on one database. The user and the database stay.
curl -X DELETE "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/database-users/$DB_USER_ID/privileges" \ -H "Authorization: Bearer $HOSTUP_API_KEY" \ -H "Content-Type: application/json" \ -d '{"database": "abcde_shop"}'The response is 204 with no body.
Stop connections from a host
Section titled “Stop connections from a host”Remove a database access host takes a host off the list. URL-encode the host in the path: % is %25.
curl -X DELETE "https://cloud.hostup.se/api/v2/shared-hosting/$ACCOUNT_ID/database-access-hosts/192.0.2.10" \ -H "Authorization: Bearer $HOSTUP_API_KEY"The response is 204 with no body, also when the host was not on the list.
What happens next
Section titled “What happens next”Every call here returns at once. There is no job to follow. No e-mail goes out and nothing is invoiced.
Errors you may hit
Section titled “Errors you may hit”- 400
password_too_weak: the password breaks a rule.detailsays which. When it is too easy to guess,suggestionslists ways to make it stronger. Send a longer generated password. - 502
upstream_failed: the control panel refused the change.detaildoes not say why. The cause is often in the request itself. Sending it again unchanged then fails again. In step 4 the usual cause is a user name that exists already, is longer than 32 characters or lacks the account’s prefix on a server that uses prefixes. In step 5 it is a database name that does not exist on the account. Check the names with List database users and List hosting databases. Then try again. - 403
forbidden: withrequiredScopes, the key lacks a scope (Keys and scopes). Without it, the account is not active. CheckserviceStatusfrom step 1. - 409
account_not_eligible_cpanel: the account is on Hostup’s previous hosting platform. Contact support. Hostup moves the account to cPanel at no extra charge. No new hosting plan is needed. Such an account shows an empty list in step 2, withcanCreate.allowedtrueall the same.
Next: Create an email account
Related endpoints
Section titled “Related endpoints”- List web hosting accounts
- List hosting databases
- Create a control panel login link
- List database users
- Create database user
- Grant database privileges
- Revoke database privileges
- Reset database user password
- Delete database user
- List database access hosts
- Allow a database access host
- Remove a database access host
- Get connection details for web hosting