A number produced without questions is a warning, not a service level. A competent team will come back with clarifying questions before any number: about who owns the data and what happens on failure. A supplier that commits to a figure without asking anything is simply working from a template, typescript software and the gap becomes a change request later — on your budget.
Look out for a gap between the engineers on the sales call and those who eventually appear in the repository. Insist on the names and CVs of the actual team in the contract, with wording that requires notice before anyone is swapped. A vendor that will only describe a pool of resources and refuses to name specific engineers is keeping the option to staff you with whoever is free.
Ask for commit-level visibility from the start. A team that hands over nothing between demos is asking you to take delivery laravel or ruby on rails faith. Visible commits reveal who is really on the project far better than a slide deck. The same applies to the CI pipeline: if nothing runs automatically, assurances about quality remain just talk.
Ambiguous wording in the contract around IP is never a formality. The contract needs to state in plain terms that the code, designs and documentation transfer to the client upon settlement of the relevant invoice. Check also the jurisdiction and the payment schedule: a large upfront payment with no milestone tied to it removes the only leverage you have.
Finally, pay attention to communication. Confirm how many hours there will be with your working day, which named person is expected to answer questions and on what response times. A few hours of overlap generally works; no overlap converts every clarification into a day of delay. Sloppy written English in the early emails rarely improves once the work starts.