# Quote template your client can approve in one click

Short answer: most "quote template" results are a Word or Excel document
you fill in and email — this is a different thing on purpose. It's a
hosted quote page your client opens, reviews, and approves, so you get a
recorded, timestamped acceptance instead of hoping for a "looks good, go
ahead" reply buried in email. If what you actually want is a printable PDF
document, a document template is the right tool and this isn't it.

## The template

Replace the scope, pricing, and `close_at` before posting:

```json
{
  "schema_version": 1,
  "kind": "form",
  "title": "Quote #Q-2026-041 — Acme Design Co.",
  "description": "Valid through August 19, 2026. Reply to the email this came in with any questions.",
  "settings": {
    "collect_respondent": "email_required",
    "close_at": "2026-08-19T00:00:00Z"
  },
  "sections": [
    {
      "key": "quote",
      "title": "Quote details",
      "questions": [
        { "id": "scope", "type": "statement",
          "title": "Quote #Q-2026-041 · valid through August 19, 2026",
          "body": [
            "Website redesign — homepage and pricing page: $2,400",
            "Contact form + CRM integration: $600",
            "Estimated total: $3,000",
            "Estimated timeline: 3 weeks from approval"
          ] },
        { "id": "scope_correct", "type": "yes_no",
          "prompt": "Does the scope and pricing above match what you're expecting?",
          "required": true },
        { "id": "requested_changes", "type": "long_text",
          "prompt": "What would you like changed?", "rows": 4,
          "show_if": { "question": "scope_correct", "op": "eq", "value": "no" } },
        { "id": "approval", "type": "consent",
          "prompt": "I approve this quote for $3,000 and authorize the work described above.",
          "show_if": { "question": "scope_correct", "op": "eq", "value": "yes" },
          "required": true },
        { "id": "deposit", "type": "payment",
          "prompt": "Secure your spot with a deposit",
          "show_if": { "question": "scope_correct", "op": "eq", "value": "yes" },
          "price_options": [
            { "value": "deposit_50", "label": "50% deposit", "amount_cents": 150000, "detail": "Balance due on delivery" },
            { "value": "pay_full", "label": "Pay in full", "amount_cents": 300000, "detail": "10% discount applied" }
          ],
          "button_label": "Pay deposit" }
      ]
    }
  ]
}
```

## What each piece is doing

- `kind: "form"` — one scrollable page rather than one question per screen,
  which suits a document-style quote people read top to bottom.
- `collect_respondent: "email_required"` — the approval is tied to a real
  email address, so "who approved this and when" is never in question.
- `close_at` — quotes should expire. Set it to your validity date and the
  page stops accepting responses automatically; you're not honoring a price
  from three months ago because nobody remembered to take the link down.
- The `statement` holds the itemized scope and price. It's display-only —
  respondents can't edit it, which is exactly what you want on a quote.
- `scope_correct` (`yes_no`) branches two ways via `show_if`: "no" opens
  a `long_text` box for requested changes instead of pushing an unhappy
  client toward approval; "yes" reveals the `consent` approval and the
  deposit payment.
- `approval` is a required `consent` question — a timestamped record that
  the client agreed to the scope and price, which is your paper trail if a
  dispute ever comes up.
- `deposit` is a native `payment` question with `price_options`, so the
  client picks 50% deposit or pay-in-full right there on the same page they
  just approved — no separate invoice step required to collect money up
  front.

## The payment question, honestly

Native Stripe payment collection inside a quiz is real and live, with real
constraints worth knowing before you build around it:

- **Business plan ($49/mo) only.** Pro and free accounts can't add a
  `payment` question.
- The creator has to finish Stripe onboarding at
  [quizgen.dev/dashboard/payments](https://quizgen.dev/dashboard/payments)
  first — without it, creating the quiz returns 402 `payments_not_ready`.
- Price is either a fixed `amount_cents` or, like the example above,
  2–10 `price_options` the respondent picks from. Amounts are in cents;
  minimum 50 ($0.50).
- **Maximum one `payment` question per quiz.** You can't stack a deposit
  question and a separate "pay in full" question — that's what
  `price_options` is for.
- The money goes straight to your own Stripe account; QuizGen takes a 2%
  platform fee on top of Stripe's own processing fee.
- The stored response records `paid: true` and the Stripe `payment_intent`
  id — that's your reconciliation key if you need to look the charge up in
  the Stripe dashboard.
- `required: true` on the payment question blocks submission until payment
  succeeds; leave it `false` (as above, implicitly) if you want approval to
  go through even when someone isn't ready to pay a deposit yet.

If you're not on the Business plan, or haven't finished Stripe onboarding,
drop the `deposit` question and use `completion.redirect_url` to send
approved clients to an external payment link (Stripe Payment Link, PayPal.me)
instead — see the [invoice template](/blog/invoice-template) for that
pattern in full.

## The workflow this replaces

Quote approved → deposit paid → you send the
[invoice](/blog/invoice-template) for the remaining balance once the work
is delivered. Three short, purpose-built pages instead of one bloated
document that tries to be an estimate, a contract, and a receipt at once —
and each step leaves its own timestamped record.

Set a [webhook](/blog/quiz-response-webhooks) on the quote and every
approval (with the `paid` flag and `payment_intent` id, if a deposit came
through) POSTs to your endpoint immediately — route it into your project
management tool or accounting software the moment a client says yes.

## Let an AI assistant fill it in

Connect [QuizGen's MCP server](/mcp)
and say something like:

> Read https://quizgen.dev/blog/quote-template.md and build me a quote for
> a kitchen remodel: $18,000 total, valid for 14 days, with a 30% deposit
> option and a pay-in-full option with a 5% discount. Give me the link to
> send my client.

## FAQ

**What if my client wants a PDF, not a link?** Use a document template
instead — Word, Google Docs, or a dedicated estimating tool. This template
is for when you want a recorded "yes," not a printable file.

**Can I limit the quote to one client?** Yes — add `"max_responses": 1` to
`settings` so the link closes after the first approval, in addition to
sending it only to them.

**What happens after `close_at` passes?** The page stops accepting
responses and shows "no longer accepting responses." Existing responses
stay readable. POST a fresh quote (new `close_at`) if you need to re-offer
it.

**Do I have to collect a deposit?** No — drop the `deposit` question
entirely and the quote still works as an approval record on its own.

**Can I require the deposit before approval counts?** Set
`"required": true` on the `payment` question if you want the response to
stay incomplete until payment succeeds; otherwise approval and payment are
independent, and someone can approve now and pay later.

---

Full schema, question types, and endpoints: [quizgen.dev/llms.txt](/llms.txt).
