Contract ids are minted as `contract-${crypto.randomUUID}`. The public read endpoint takes the id as its only credential, returns just the fields needed to render (never the full audit trail), and is IP rate-limited to 30 reads/minute; signing is limited to 5 submissions/minute.
Also called: no login contract · contract link · password-less signing · secure contract url
- 1submit-form generates the contract id with crypto.randomUUID().
- 2/api/client-portal/contract?id=… returns rendered body, status, both signature blocks, required sections and captured initials.
- 3ipRateLimit guards both the read and the sign endpoints.
- 4The customer page and the builder's view-mode modal both read through this one endpoint.
The reasoning is written out in the submit route: 'Contract ids are the public-facing secret protecting the contract (no Clerk session involved on /api/client-portal/contract — auth is via id-as-secret). The makeId helper only gives ~26 bits of random entropy… Using crypto.randomUUID gives 122 bits of cryptographic randomness, making brute-force exhaustion permanently impractical regardless of rate-limit posture.'
- Signature friction caused by account creation
- Weakly-random public document ids
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →