Begin with the reason this software should exist, not your preferred technology. Which people will use the system, with what frequency, and what happens today? An estimator staff augmentation company who grasps the purpose often proposes a cheaper route to it; one who only sees the requirements as given prices your assumptions along with the work.
Set out the scope as user stories or scenarios: a walk through each important path. Every bit as useful, write down what is out of scope. An explicit list of exclusions prevents more argument later than the rest of the brief combined. Mark too which items are decided and which may still change — the difference between laravel and ruby on rails changes the price, and hiding it only hurts you.
List the constraints. This means systems you must integrate with, existing databases and their quality, security and compliance rules, expected load, supported browsers or devices and any technology you are committed to. If there is a hard date, say why: an experienced team can often resequence the work to hit it, but not if the date is a secret.
Say what completion means for each item. Acceptance criteria do not need any formal notation: a plain-language note describing the expected behaviour is enough. That one addition shortens acceptance testing considerably and removes the most common source of disputes.
One last thing, say what you expect back. Request a task-level breakdown, a written list of assumptions, the risks the team sees and an optimistic and custom development vs saas a pessimistic figure. Read a wide range as information, not evasion: it normally identifies exactly which requirement is unclear. Then clarify that area and ask for a new estimate — the revised figure will be the one worth planning around.