A manufacturing client in Faridabad rang us in March. Their product page needed two lines changed — a spec update, nothing dramatic. The previous agency had handed them a zip eighteen months earlier called final-website-v3.zip, sat on a Google Drive shared with the marketing head who had since left. The agency had shut down. The founder genuinely believed he owned his website because he had the zip on his laptop. He did not know which server it was running on. We spent the better part of a day just figuring out that the DNS sat inside a GoDaddy account belonging to the defunct agency's proprietor, whose personal Gmail was the only recovery address, and whose phone number was no longer in service. The zip was useless. Not because the code was bad — it was a fairly standard Astra-and-Elementor build — but because the code was the least valuable thing in the handover.
That rescue is the reason we keep writing about this. Every six months or so we inherit a site where the client technically "owns" everything and operationally controls nothing. The zip is a decoy. The real handover lives across six different places, and if any one of them is missing, the client is locked in.
What Clients Think They Are Getting vs What Arrives in the Zip
When a client signs an SOW that says "source code will be handed over at project completion", they imagine — reasonably — that they will receive a working copy of their website that someone else can pick up and continue. What they usually receive is a directory dump. wp-content, a SQL file from a month before launch, a README that says "install on PHP 8.1" and nothing else. No .env template. No list of which plugins are licensed and which are nulled (and yes, that happens, more often than anyone admits — we have inherited at least four sites in the last two years running cracked versions of premium plugins, which is a separate disaster). No note about the cron job that rebuilds the product cache every six hours. No mention of the Cloudflare account in front of the origin.
The zip is necessary but it is roughly the first 15% of what a handover actually contains. The other 85% is operational: who can log into what, whose name is on the bill, whose email gets the renewal notice, and what to do at 11pm on a Saturday when the checkout breaks.
The Six Asset Classes a Real Handover Transfers
We split handover artefacts into six buckets. Not because six is a clean number — it isn't, the honest count is closer to seven if you separate analytics out — but because these six are where missing transfers cause the most pain on rescue projects.
Code. Not a zip. A Git repository — usually GitHub or Bitbucket — where ownership of the organisation has been transferred to the client's account, not "we added your email as a collaborator". There is a difference, and the difference matters the day we leave the project. Along with the repo: a .env.example with every variable documented (what it is, where to get a fresh value, what breaks if it's wrong), a database export with the exact mysql or pg_restore command needed to bring it back, and a written list of every cron job — both server-level and WP-Cron — with its schedule and its purpose. We lost three days on a recovery project once because a nightly cron was regenerating sitemap files and nobody knew, so the new team kept overwriting them in Git.
Credentials are the next one, and the rule we hold to is hosting account ownership rather than sub-user access. If the site runs on Cloudways (Vultr 2 GB is the typical small-business pick), the Cloudways account itself should be in the client's name, with the billing card being the client's card, and the agency added as a team member with deploy rights. Same with Hostinger — a Business plan in the client's name, not the agency's reseller account. Same with DigitalOcean if it's a custom Node or Next.js build. The billing email and the technical email should be different addresses inside the client's domain, so that when the marketing manager leaves, the renewal notice doesn't bounce.
DNS comes after that, and it is the one that catches almost everyone. The registrar logins. The nameserver records. If Cloudflare sits in front, the Cloudflare account ownership. We will come back to this in the next section because it is where the Faridabad story actually broke.
Licences are the fourth bucket — ThemeForest single-site licences, Elementor Pro activations, WPRocket, Gravity Forms, the lot. These are the quiet traps and they deserve their own section too.
Content is the fifth. Original logo files in vector. The brand colour values (hex, not screenshots). Product photography in the highest resolution the photographer delivered, not the compressed WebP versions sitting on the server. Copy decks. Anything the client paid a writer or designer to produce, in editable form. We had a Gurgaon client whose entire brand book existed only as a PDF because the previous agency had refused to share the InDesign files. They had paid for the work. They did not have it.
Runbook. A one-page document — we will describe ours at the end — that tells whoever inherits the site how to deploy, how to roll back, where the backups live, who to call, and when to update plugins. Without this the other five buckets are inert. Code without a runbook isn't useless exactly — it just sits there until someone with the time and the stubbornness reverse-engineers what the previous team already knew.
Where Licences and DNS Quietly Trap You
Two places where the lock-in is almost always accidental — and where, in our experience, the client only finds out about it eighteen months in, usually on a Tuesday when something else is already on fire.
Licences first. A ThemeForest regular licence is single-use and tied to the Envato account that purchased it. If your agency bought the Avada or Astra Pro licence on their Envato account and installed it on your site, you do not own that licence. You are using it. When the renewal comes around — typically a year later for support and updates — the renewal notice goes to the agency, the renewal payment goes off the agency's card, and if the relationship has ended, the licence simply lapses. The theme keeps working but security patches stop. Same story with Elementor Pro, which has activation limits per licence tier (we think it's something like 1, 3, 25, or unlimited depending on the plan — Elementor has reshuffled their tiers more than once, so check the current page before you assume anything). If the agency activated your site against their multi-site licence, your site occupies one of their slots, and when they deactivate it — for whatever reason — Elementor Pro features stop working on your live site. We have seen a client's checkout form vanish on a Tuesday morning because of exactly this.
The honest answer is that every premium plugin and theme licence should be purchased on an Envato or vendor account owned by the client, billed to the client's card, with the agency added as a technical contact. Slightly more friction at project start, and it saves what is usually a small disaster eighteen months in — or a large one, depending on how central the plugin is to the checkout.
DNS is the other quiet trap, and the Faridabad rescue is the canonical example. The domain itself was registered in the founder's name through GoDaddy — that part was fine. But somewhere along the way the previous agency had moved the nameservers to Cloudflare for caching, and the Cloudflare account belonged to the agency's proprietor's personal Gmail. When we tried to update an A record to point at the new server, we couldn't. We ended up doing a registrar-level nameserver change back to GoDaddy's default DNS, which works, but it cost us a TTL window — we set it down to 300 seconds the night before, did the cutover at 2am IST on a Sunday, and even then a handful of users hit the old IP for a few hours because of ISP-level caching. The whole episode took about ten days from first call to clean cutover. The actual code change to the product page took eleven minutes.
The same trap exists with Razorpay and Cashfree merchant accounts. If the merchant account was opened in the agency's name "to get the integration done faster" — and we have seen this suggested by agencies, which is borderline negligent — the settlements go to the agency's bank account, the PAN on file is the agency's PAN, and the GST liability sits on the agency's books. Both Razorpay and Cashfree merchant accounts should be in the client's registered business name from day one, with the agency added as a technical user. Non-negotiable. We refuse projects where the client wants us to take this on, and we tell them why.
While we are on accounts that should never sit with us: Google. GA4 property ownership, not just "Admin" access — there is a meaningful difference between being a primary owner and being granted edit rights, and the difference becomes apparent the day the primary owner's Gmail gets suspended. Search Console verification should be done via DNS TXT record so it survives a hosting change, not via an HTML file in the document root that gets nuked the first time someone redeploys. Google Business Profile (the artist formerly known as GMB) ownership transferred to the client's Google account, with the agency as a manager.
And — this is the one we get pushback on most — we will not host client sites under our own Cloudways or DigitalOcean billing account, even when the client asks us to "just bill us monthly, it's easier". It is easier. It is also how clients end up locked in. We have inherited at least two sites where the previous agency was acting as an unofficial reseller, and when the agency went quiet on a payment dispute, the client's site went down because the agency's card had been declined. We learned this the hard way on a build in 2021 and we don't do it any more.
The One-Page Runbook We Leave Behind in Week Six
Our six-week builds end with a single document. One side of A4 if printed, though nobody prints it. Markdown in the repo, PDF exported to the client's shared drive, link in the project closeout email. It contains, more or less:
- The deploy command. Literal.
git push production mainornpm run deployor whatever the project uses, with the expected output and the rough time it takes. - The rollback command. Equally literal. How to revert the last deploy if something breaks within ten minutes of pushing.
- Backup location and frequency. We usually run nightly database backups to a separate S3 bucket (or Backblaze, depending on the client's preference and budget), retained for 30 days, plus weekly full-server snapshots retained for 90. The runbook says exactly where they are and how to restore one.
- Plugin and core update cadence. Our default recommendation: security patches within 48 hours, minor updates monthly on a staging environment first, major version updates quarterly with a proper QA pass. The runbook records this for the next team.
- Emergency contacts. Hosting support number (Cloudways and Hostinger both have decent chat support, which we note), Razorpay merchant support, the domain registrar's support number, and — if applicable — the SSL provider.
- Known quirks. Every site has them. "The product import script times out on batches over 400 SKUs, run it in two passes." "Cloudflare's Rocket Loader breaks the Gravity Form on the contact page, leave it disabled for that page rule." Two or three lines, but the kind of thing that takes the next developer half a day to rediscover.
That's the runbook. Not elegant. Not comprehensive. It is the thing we wish we had been handed on every rescue project we have ever taken on, and so it is the thing we leave behind on every project we ship.
One more thing, which belongs in the SOW rather than the handover itself. Before you sign with any agency, the source code ownership clause should read something close to: "All source code, design files, content, and associated digital assets produced under this agreement are the property of the Client. The Agency shall transfer, at project completion, ownership of the project Git repository, all hosting and registrar accounts, all third-party licences purchased on the Client's behalf, and shall provide a written operations runbook. The Agency retains no licence to redistribute or reuse Client-specific code or assets." That last sentence matters. Without it, agencies sometimes claim a perpetual licence to reuse "framework" code that turns out to be 80% of your build.
We still get the licence transfer wrong about one project in eight — usually because the client buys a plugin halfway through and forgets to tell us whose card it was on, or because someone on our side activates a staging copy against the production licence and then nobody updates the inventory list before close. The handover is only ever as clean as the project was, and no project is perfectly clean. Anyway. If you want a useful test before you sign anything: ask the agency for a redacted sample handover packet from a previous client — the runbook, the credential checklist, the licence list. If they have to invent one to send you, you already know what kind of handover yours is going to be.

