A handover that consists of a repository link and a call is not a handover. Here is what a complete one contains and how to verify it rather than accept it.
Code and history
The full repository, in an organisation you control, at the delivered version, with complete commit history. Branch protection and access configured for your team rather than the supplier.
Everything that is part of the system, not only the application: infrastructure configuration, database migrations, seed and fixture data, build scripts, and the continuous integration pipeline definition.
A tagged release matching exactly what is running in production, so there is no ambiguity about which commit is live.
Legal
The intellectual property assignment, executed, covering everything built for you. Not a licence, an assignment.
A dependency inventory listing every third party package with its licence, so your legal team can review the position rather than discover it during due diligence.
Any carve outs stated explicitly with the licence terms that apply to them.
Infrastructure and access
Every account registered to your organisation: domain registrar, hosting platform, database provider, object storage, email provider, monitoring, error tracking and any other third party service the system depends on.
An access inventory listing who currently holds credentials to what, so you can revoke the supplier when you choose.
Secrets in your platform secret store, scoped per environment, with the rotation procedure documented. Not in a spreadsheet, not in a chat thread.
DNS records documented, including what each one is for, because the one nobody can explain is the one that breaks something in eight months.
Documentation
An architecture description: the components, how they communicate, why the significant decisions were made, and what was deliberately not done.
A data model reference covering the schema, the constraints, the indexes and what each significant field means.
An integration reference for each third party system: the interface used, the authentication method, the failure behaviour and the reconciliation approach.
A deployment guide written for someone who was not on the project, taking them from a clean environment to a running system.
A runbook covering deploy, rollback, backup, restore, key rotation, and the failures most likely to occur with what to do about each.
An environment variable reference listing every variable, what it does and what happens if it is missing.
Operational verification
These are the items that separate a real handover from a paperwork exercise.
A restore that has actually been performed and timed, with the recovery time recorded in the runbook. A backup nobody has restored is a hypothesis.
A rollback that has actually been executed, so the procedure is known to work rather than assumed to.
Monitoring and alerts routed to your team rather than the supplier, verified by triggering one.
Tests
The automated test suite, the fixtures and the seed data, plus instructions for running it locally and in the pipeline.
A note on what is covered and what is not. Honest coverage information is more useful than a percentage, because it tells a new team where the risk is.
The test that matters
Give the documentation to a competent engineer who has never seen the system, and ask them to deploy it into a clean environment without asking anyone a question.
Everything they have to ask is a gap in the documentation. Record those gaps against the agreed handover scope and resolve them before the engagement closes. Do not assume extra work has no cost unless the contract establishes that.
Do the same for the runbook: ask them to perform a restore following only the written procedure.
Timing
Handover is not a final task. The documentation should be written as the system is built, because reconstructing the reasoning behind a decision six months later produces documentation that describes what the code does rather than why.
Schedule the verification walkthrough before the final milestone, not after it. The people delivering the system can then answer questions while the details are still current.
Verify the access transfer without exposing secrets
Use an access register that lists the service, account identifier, client administrator and the location of the credential. The register should not contain the secret itself. During the walkthrough, have the receiving administrator sign in using their own identity and confirm that recovery methods belong to the client, not to a supplier's personal mailbox.
Rotate credentials in an agreed order. Replacing an email API key before updating the application's secret store can interrupt notifications. Document which services accept overlapping keys, which require a coordinated change and how to verify the replacement. Keep the rollback procedure appropriate to the service rather than treating an old leaked key as a safe fallback.
Check alerts with the new access arrangement. A monitor can remain green while its notifications still go to an inactive supplier account. Trigger a controlled test event, confirm receipt by the intended operational contact and remove the test event afterwards without deleting the evidence of the check.
Record exceptions explicitly. A database backup that cannot be restored in the available test environment is an unverified recovery path, not a completed checkbox. State what was tested, what was not and who is responsible for the remaining test. This makes the handover useful to the next engineer and prevents a documentation inventory from being mistaken for proof that every procedure works.
Keep the signed acceptance record with the delivered release identifier. The receiving team should be able to tell which artefacts and checks belong to the version they actually received.