Look first at relevant experience, not the length of the client list. Ask to see a couple of engagements that resemble your stack, and then find out whether those engineers are still with the software product development company. An honest provider is happy to connect you with the engineers. Evasive answers at this stage generally mean the demo work came from somewhere else.
The agreement warrants more scrutiny than the proposal. Three clauses do most of the work: assignment of intellectual property, the NDA, and notice periods and handover. Everything produced should transfer to you as it is paid for, along with documentation, pipelines and deployment scripts. Watch for any clause that leaves so-called reusable libraries outside the transfer, since this is frequently the dependency that makes switching painful.
Ask where their numbers come from. An honest estimate arrives with a list of assumptions, a breakdown per feature and a best case and a worst case. A fixed-price contract is only reasonable when the scope is genuinely frozen; otherwise the provider prices the risk in and you fund the buffer regardless. Hourly billing shifts that risk to you, so it demands visible weekly reporting and a spending cap.
How the work is run matters more than headcount. Find out how a new requirement enters the plan, who signs off on a feature and which is better livewire or alpine js how testing is organised. A team should be able to demonstrate a working build every one or two weeks. Written acceptance criteria stay the only reliable protection against the it-was-never-in-scope conversation.
Before signing, plan for the handover at the start rather than at the end. Require that the repository stays under your account from the first commit, and that the documentation is refreshed in every sprint. A partner who is comfortable with this accepts it without argument; hesitation here says most of what you need to know.