Every sent quote has a public URL of the form /q/{48-char-token}. The token is unguessable; the URL is safe to paste into a message or email.
What the client sees
- Your business name, logo, brand color at the top.
- The quote number and the valid-until date.
- A line-item table: description, quantity, unit price, line total.
- Any optional items with a checkbox to add.
- Subtotal and total, updating live as they check/uncheck optional items.
- "Accept" and "Decline" buttons.
When the client accepts
- They check any optional items they want to add.
- They click Accept.
- If you have deposit collection configured (Stripe Connect + deposit_cents on the quote), they enter a card.
- The quote flips to
acceptedstatus. - You get a notification in your inbox + audit log.
When the client declines
They click Decline. An optional textarea asks for a reason. Submitting marks the quote declined. You see the reason on the quote detail page.
Capture decline reasons even when they are not flattering. "Price is too high" and "Went with cheaper competitor" are the two most-common; knowing which is which tells you whether to adjust pricing or differentiation.
First-view tracking
When the client opens the public URL, the status flips from sent to viewed on the first visit. Subsequent visits do not re-trigger. This gives you a signal: "quote has been seen but not acted on" vs "quote has not been opened."
The accept token is single-use for the accept action but multi-use for viewing. A client can open the URL multiple times. They cannot accept twice — a second accept attempt returns a "Already accepted" page.