---
title: "POST /v1/quotes — Gap 21"
method: POST
path: "/quotes"
tags: ["Quote"]
---

# POST /v1/quotes — Gap 21

`POST /quotes`

Creates a Lead with status='quoted' (or 'draft' if email+event_date
aren't both present, mirroring native QuoteController::save status
gating) and a UUID token. quote_data snapshots the booking-shaped
payload so /book/resume/{token} can rehydrate the wizard.

Response carries `customer_portal_url` pointing at the tenant
subdomain's resume route — that's the link partners email to the
customer to invite them back to complete payment.

Idempotency: protected by the public-api idempotency middleware
(same pattern as POST /v1/bookings).

## Request body

- StoreQuoteRequest — Gap 21 — POST /v1/quotes payload validation. Mirrors POST /v1/bookings payload (booking-shaped) MINUS payment fields (no payment_option, no offline_payment_method_id, no payment_intent). Same dual-shape support: either prefixed `customer_id` OR flat `email` + `name` (auto-resolves a Customer via CustomerResolver). Catalogue references (package_id, unit_type_id, unit_id, extras) use prefixed ids and cross-tenant-validate against the current tenant.
  - `customer_id` string, nullable — Customer reference — either or
  - `name` string, nullable
  - `email` string, email, nullable
  - `phone` string, nullable
  - `package_id` string, nullable — Catalogue references
  - `unit_type_id` string, nullable
  - `unit_id` string, nullable
  - `event_date` string, date-time, nullable — Event details
  - `event_time` string, nullable
  - `event_type` string, nullable
  - `event_name` string, nullable
  - `event_duration_hours` number, nullable
  - `venue_address_line1` string, nullable — Venue address — same shape as POST /v1/bookings
  - `venue_address_line2` string, nullable
  - `venue_city` string, nullable
  - `venue_postcode` string, nullable
  - `venue_country` string, nullable
  - `venue_latitude` number, nullable
  - `venue_longitude` number, nullable
  - `coupon_code` string, nullable — Discount + free-form fields
  - `customer_notes` string, nullable
  - `metadata` string[], nullable
  - `extras` object[], nullable — Extras line items
    - `extra_id` string
    - `quantity` integer

## Response `201`

- string

## Other responses

- `422` — Validation error

---

[API](https://skmtc.dev/boothzen/apis/boothzen-api-v1.md) · [All operations](https://skmtc.dev/boothzen/apis/boothzen-api-v1/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/boothzen/boothzen-api-v1/revisions/a5ae040e3ba3/schema)
