DEV Community

Cover image for How to transfer a finished app to your client on Hubfly space
octave Nkurunziza
octave Nkurunziza

Posted on Originally published at blog.hubfly.space

How to transfer a finished app to your client on Hubfly space

TL;DR

  • What you get: the client's app, volumes, databases, buckets and domains moved into the client's own Hubfly space account, still running at the same URLs.
  • Who it's for: freelancers, agencies and anyone moving a side project into a company organization.
  • Time needed: a few minutes in the dashboard. The switch happens at the next full hour (UTC).
  • Cost: the transfer is free. The client needs balance for about 72 hours of running cost (about $0.43 for a small app with a database).

You finished the client's app. It runs in your account, on your card, and your login is the only way in. Now the client wants it in their name. The usual fix: a weekend rebuilding it all in their account.

This guide moves the whole project into the client's account in one offer, with nothing redeployed and no downtime. A clean handover gets you paid. You stop paying their hosting bill. And nobody calls you at 2 a.m. when their card expires.

Try it on Hubfly space (start free, 360 hours included).

What a project transfer moves

Everything inside the project goes with it: apps, volumes, Boxes, databases, buckets, Mail and domains. Nothing restarts, and the URLs stay the same. What changes is who owns it, who pays and who can log in.

Three limits to know up front:

  • The project stays in the same region. To change region, use Region Migration separately.
  • One offer link can carry up to 20 projects, for example the web project and the database project it uses.
  • The offer link is valid for 7 days.

Step 1: Get the project ready for handover

Do this before you send anything. Each item avoids a support ticket later.

  1. Stop anything in progress. A running build, deploy or move blocks the offer. So does an open terminal or tunnel session.
  2. Bundle connected projects. A database or Realtime server connected to a project in another account blocks the offer, and so does a volume shared across projects. Transfer them together, or disconnect them first.
  3. Check what can't move. Projects with GPU instances (paid from your personal GPU wallet), projects linked to an AI Builder workspace, projects inside a sub-account, and projects in a region under maintenance can't be sent.
  4. Check who can send. A personal project is sent by its owner. An organization project is sent by an owner of that organization, and the organization must be active. Your balance must be above zero.
  5. Clean your secrets out of the environment. Every environment variable, secrets included, becomes readable by the client. Remove any personal token of yours before you send.
  6. List the keys the client must re-create. Storage S3 access keys, Mail SMTP logins and Mail REST keys always stop working at the handover. Deploy webhook URLs are turned off. Note every place they're used.

The preview in the next step names each blocker too, but fixing them first means the client isn't left waiting on an email.

Step 2: Open Transfer Project and read the preview

Open the project, click the gear icon next to its name, then Danger Zone → Transfer….

The Danger Zone in Project Settings, with Transfer Project between Move to another region and Hibernate Project

The preview has three parts:

  • What moves: a count of each resource type, such as containers and volumes.
  • Credentials revoked for people who lose access: keys, tokens and passwords that stop working. By default everyone is removed at the handover, you included.
  • Before you send: warnings, such as free-tier containers counting against the new owner's free tier.

The transfer preview listing 1 container and 1 volume, no revoked credentials, and a free-tier warning

Read it with the client's eyes. If a credential on that list feeds a payment webhook or a CI job, write it down now.

Step 3: Send the offer with an email code

  1. Enter the client's email address in Recipient email.
  2. Decide on Also revoke the credentials of people the recipient keeps. Tick it to stop every API key and token of the project, even for people who stay. That's the safe choice if contractors have had keys.
  3. Click Email me a code. A 6-digit code goes to your email. It's valid for 15 minutes.
  4. Type the project name and the code to confirm.

The recipient email field, the revoke-all checkbox and the Email me a code button

The form never says whether the client already has an account, which protects their privacy. No account yet? They sign up with that email, then click the link.

Only a signed-in dashboard session can send, accept, decline or cancel. API keys and access tokens can't, so a script can't give a project away by accident. Changed your mind? Cancel the offer any time before the owner change starts.

Step 4: The client accepts and picks where it goes

The client clicks the link in the email. They see who's sending, what's inside each project, its domains and who has access today. Then they pick their personal account or one of their organizations and check two things:

  • Money: enough balance for roughly three days of the project's running cost, plus any Mail plans that bill them from the handover.
  • People and keys: who keeps access and which keys stop working. Direct members are removed unless the client keeps them, so ask to stay on if you have a support retainer.

To accept into an organization, the client must own it or have a role that can both create projects and manage billing.

Step 5: Wait for the hour, then finish the checklist

The owner changes at the next full hour (UTC). Until then, you keep paying. Usage up to that hour is billed to you, and everything after it to the client.

During the switch, deploys and config changes pause, but the app keeps serving traffic. If something fails before the owner changes, the transfer rolls back and the project stays with you. Both of you get an email at the end, and the project's History records the transfer.

Then send the client this short after-handover list:

  1. Rotate the secrets you've seen. Database passwords, Box root passwords and SSH keys are still known to you.
  2. Create new Storage and Mail keys and put them where the old ones were.
  3. Turn deploy webhooks back on. Each one gets a new URL.
  4. Link the Git repository again. Automatic deploys from Git are off, because the repository connection was yours. To deploy on every push from CI, follow this GitHub Actions guide.
  5. Set a budget cap. The Monthly Cap starts a new period for the new owner. When spending hits the cap, workloads stop. No surprise bill, but the app goes offline, so leave headroom.

What it costs

The transfer itself is free. The client needs balance for about 72 hours of running cost before accepting. Here's the math for a small always-on client app with a database, at Hubfly space rates (730 hours a month):

Part Monthly 72 hours
CPU, 0.5 vCPU: 0.5 × $0.004 × 730 $1.46 $0.14
RAM, 512 MB: 0.5 × $0.002 × 730 $0.73 $0.07
Container disk, 4 GB (example size): 4 × $0.00001536 × 730 $0.04 $0.004
Volume, 10 GB: 10 × $0.00001536 × 730 $0.11 $0.01
Managed PostgreSQL Nano, 10 GiB ≈ $2.02 ≈ $0.20
Total ≈ $4.37 ≈ $0.43

So a client with $5 of credit can accept this project with room to spare. New accounts make a one-time deposit of $5 or more before creating resources. It stays in the account as prepaid credit, not a fee.

What can go wrong

1. The preview shows a blocker. Usually a deploy still running, an open terminal or tunnel, a shared volume, or GPU instances. Fix it and reopen Transfer…; the preview checks again each time.

2. The client can't accept. They're short on balance or at an account limit: a static IP, Mail projects, free Mail addresses, or managed database and Realtime counts. They top up or free the limit, then open the same link within the 7 days.

3. Something broke right after the handover. Almost always a revoked key: an S3 key in the app's environment, an SMTP login, or a CI job calling the old deploy webhook. Create new ones and update those places. Revoked keys stay revoked, even if a transfer rolls back.

Who this is NOT for

  • Moving to another region. A transfer keeps the region. Use Region Migration for that.
  • Sharing access while you keep paying. Add the client as a project member instead.
  • One copy of an app per customer. A transfer moves one running project. For a deployment per customer, use sub-accounts, and note that sub-account projects can't be transferred.

Go further on Hubfly space

All details are in the Project Transfer docs.

Start free, 360 hours included. Build the client's app on Hubfly space and hand it over with one link when it's done. Running an agency with many client projects? Talk to sales about organizations.

Top comments (0)