{"openapi":"3.1.0","info":{"title":"QuotWay API","version":"2026-10-01","description":"Read and create B2B quotes in your QuotWay store. Enterprise plan. Money is a decimal string with an ISO currency; timestamps are ISO-8601 UTC; errors are RFC 9457 problem+json. Rate limits: 120 requests/minute per key, 300 per store.","contact":{"name":"QuotWay support","url":"https://www.quotway.com/docs/api"}},"servers":[{"url":"https://api.quotway.com"}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","description":"An API key from Settings → Integrations → API keys (qw_live_… / qw_test_… for development stores). Send `Authorization: Bearer <key>`."}},"schemas":{"QuoteSnapshot":{"type":"object","properties":{"object":{"type":"string","enum":["quote"]},"id":{"type":"string"},"number":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string","enum":["wholesale","b2b"]},"currency":{"type":"string"},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"accepted_total":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"headline":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"headline_mode":{"type":"string","enum":["none","full","decided","open"],"description":"none = not accepted · full = accepted in full · decided = every line accepted or declined · open = some lines still undecided"},"updated_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"}},"required":["object","id","number","status","mode","currency","total","accepted_total","headline","headline_mode","updated_at"],"description":"PII-free summary carried on webhook payloads."},"EventType":{"type":"string","enum":["quote.created","quote.proposal_sent","quote.countered","quote.lines_updated","quote.message_created","quote.assigned","quote.accepted","quote.partially_accepted","quote.acceptance_voided","quote.declined","quote.expired","quote.reopened","quote.closed","quote.converted","quote.invoice_sent","quote.order_completed","quote.order_cancelled","quote.order_refunded","quote.merchant_approval.requested","quote.merchant_approval.granted","quote.merchant_approval.rejected","quote.buyer_approval.requested","quote.buyer_approval.granted","quote.buyer_approval.rejected","quote.expiring_soon"]},"Ping":{"type":"object","properties":{"object":{"type":"string","enum":["ping"]},"shop_domain":{"type":"string"},"api_version":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["read_quotes","write_quotes","read_customer_data","read_analytics","manage_webhooks"]}}},"required":["object","shop_domain","api_version","scopes"]},"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"code":{"type":"string","example":"insufficient_scope"},"request_id":{"type":"string"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}},"required_scopes":{"type":"array","items":{"type":"string"}},"required_plan":{"type":"string"}},"required":["type","title","status","detail","code"],"description":"RFC 9457 problem details."},"QuoteList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Quote"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page; null on the last page."}},"required":["object","data","has_more","next_cursor"]},"Quote":{"type":"object","properties":{"object":{"type":"string","enum":["quote"]},"id":{"type":"string"},"number":{"type":"string","example":"QW-1042"},"status":{"type":"string","example":"proposal_sent"},"mode":{"type":"string","enum":["wholesale","b2b"]},"source":{"type":"string"},"currency":{"type":"string"},"version_number":{"type":"integer"},"negotiation_round":{"type":"integer"},"po_number":{"type":["string","null"]},"requested_delivery_date":{"type":["string","null"],"format":"date-time","example":"2026-09-27T10:00:00.000Z"},"expires_at":{"type":["string","null"],"format":"date-time","example":"2026-09-27T10:00:00.000Z"},"created_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"updated_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"first_accepted_at":{"type":["string","null"],"format":"date-time","example":"2026-09-27T10:00:00.000Z"},"fully_converted_at":{"type":["string","null"],"format":"date-time","example":"2026-09-27T10:00:00.000Z"},"invoice_sent_at":{"type":["string","null"],"format":"date-time","example":"2026-09-27T10:00:00.000Z"},"totals":{"$ref":"#/components/schemas/QuoteTotals"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/QuoteLine"}},"proposal":{"type":["object","null"],"properties":{"version_number":{"type":"integer"},"sent_by":{"type":"string"},"created_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"shipping_status":{"type":"string"},"shipping_label":{"type":["string","null"]},"payment_terms":{"type":["string","null"]},"deposit_percentage":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"expires_at":{"type":["string","null"],"format":"date-time","example":"2026-09-27T10:00:00.000Z"}},"required":["version_number","sent_by","created_at","shipping_status","shipping_label","payment_terms","deposit_percentage","expires_at"]},"approval":{"type":"object","properties":{"active":{"type":"boolean"},"pending_domain":{"type":["string","null"]}},"required":["active","pending_domain"]},"shopify":{"type":"object","properties":{"customer_id":{"type":["string","null"]},"company_id":{"type":["string","null"]},"company_location_id":{"type":["string","null"]},"company_contact_id":{"type":["string","null"]},"draft_order_ids":{"type":"array","items":{"type":"string"}},"order_ids":{"type":"array","items":{"type":"string"}}},"required":["customer_id","company_id","company_location_id","company_contact_id","draft_order_ids","order_ids"]},"assigned_staff":{"type":["object","null"],"properties":{"id":{"type":"string"},"email":{"type":"string"}},"required":["id","email"]},"kit_conversion_mode":{"type":"string"},"based_on_quote_id":{"type":["string","null"]},"links":{"type":"object","properties":{"admin_url":{"type":"string"}},"required":["admin_url"]},"customer":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":["string","null"]},"phone":{"type":["string","null"]},"company_name":{"type":["string","null"]},"shipping_address":{},"billing_address":{},"custom_fields":{},"notes":{"type":["string","null"]}},"required":["email","name","phone","company_name","notes"],"description":"Buyer personal data — present ONLY with the read_customer_data scope."}},"required":["object","id","number","status","mode","source","currency","version_number","negotiation_round","po_number","requested_delivery_date","expires_at","created_at","updated_at","first_accepted_at","fully_converted_at","invoice_sent_at","totals","lines","proposal","approval","shopify","assigned_staff","kit_conversion_mode","based_on_quote_id","links"]},"QuoteTotals":{"type":"object","properties":{"currency":{"type":"string"},"subtotal":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"discount_total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"shipping_total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"tax_estimate":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"total":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"What was offered (current version), incl. shipping + tax estimate."},"accepted_total":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"On a MIXED acceptance: net of the accepted lines' discount share, EXCLUDING shipping and tax. Null otherwise."},"still_open_total":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"headline":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"The figure to act on — see headline_mode."},"headline_mode":{"type":"string","enum":["none","full","decided","open"],"description":"none = not accepted · full = accepted in full · decided = every line accepted or declined · open = some lines still undecided"},"base_currency":{"type":"object","properties":{"currency":{"type":"string"},"total":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"accepted_total":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"exchange_rate":{"type":["string","null"]}},"required":["currency","total","accepted_total","exchange_rate"]}},"required":["currency","subtotal","discount_total","shipping_total","tax_estimate","total","accepted_total","still_open_total","headline","headline_mode","base_currency"]},"QuoteLine":{"type":"object","properties":{"id":{"type":"string"},"quote_line_item_id":{"type":["string","null"]},"position":{"type":"integer"},"product_id":{"type":["string","null"]},"variant_id":{"type":["string","null"]},"sku":{"type":["string","null"]},"title":{"type":"string"},"variant_title":{"type":["string","null"]},"quantity":{"type":"integer"},"catalog_price":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"requested_price":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"unit_price":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"line_total":{"type":["string","null"],"pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"is_custom":{"type":"boolean"},"requires_shipping":{"type":"boolean"},"taxable":{"type":"boolean"},"buyer_visibility":{"type":"string","description":"show · price_hidden · hidden — what the buyer sees for this line"},"kit":{"type":["object","null"],"properties":{"key":{"type":"string"},"role":{"type":"string"},"title":{"type":["string","null"]}},"required":["key","role","title"]},"decision":{"type":["string","null"],"enum":["accept","reject","defer",null]},"accepted":{"type":"boolean"},"still_open":{"type":"boolean","description":"Undecided and still negotiable. A declined line is NOT still open."},"buyer_note":{"type":["string","null"],"description":"Only with read_customer_data."}},"required":["id","quote_line_item_id","position","product_id","variant_id","sku","title","variant_title","quantity","catalog_price","requested_price","unit_price","line_total","is_custom","requires_shipping","taxable","buyer_visibility","kit","decision","accepted","still_open"]},"EventList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"The id of the last event — pass as `starting_after` for the next page."}},"required":["object","data","has_more","next_cursor"]},"Event":{"type":"object","properties":{"object":{"type":"string","enum":["event"]},"id":{"type":"string","description":"Stable — equals the webhook-id header of the matching webhook delivery."},"type":{"type":"string"},"created_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"sequence":{"type":"string","description":"Monotonic ordering key (string: may exceed 2^53)."},"quote_id":{"type":["string","null"]},"actor":{"type":"string"},"data":{"type":"object","additionalProperties":{}}},"required":["object","id","type","created_at","sequence","quote_id","actor","data"]},"DocumentList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentSummary"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Always null — every document is returned (newest 100)."}},"required":["object","data","has_more","next_cursor"]},"DocumentSummary":{"type":"object","properties":{"object":{"type":"string","enum":["document"]},"id":{"type":"string"},"quote_id":{"type":"string"},"type":{"type":"string","enum":["proposal","confirmation","proforma_invoice"]},"file_name":{"type":"string"},"file_size":{"type":"integer"},"locale":{"type":"string"},"generated_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"}},"required":["object","id","quote_id","type","file_name","file_size","locale","generated_at"]},"Document":{"type":"object","properties":{"object":{"type":"string","enum":["document"]},"id":{"type":"string"},"quote_id":{"type":"string"},"type":{"type":"string","enum":["proposal","confirmation","proforma_invoice"]},"file_name":{"type":"string"},"file_size":{"type":"integer"},"locale":{"type":"string"},"generated_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"download_url":{"type":"string"},"download_url_expires_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"}},"required":["object","id","quote_id","type","file_name","file_size","locale","generated_at","download_url","download_url_expires_at"]},"AnalyticsSummary":{"type":"object","properties":{"object":{"type":"string","enum":["analytics_summary"]},"period":{"type":"string","enum":["day","week","month"]},"currency":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"period_start":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"period_end":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"quotes":{"type":"object","properties":{"total":{"type":"integer"},"new":{"type":"integer"},"accepted":{"type":"integer"},"partially_accepted":{"type":"integer"},"declined":{"type":"integer"},"expired":{"type":"integer"},"converted":{"type":"integer"}},"required":["total","new","accepted","partially_accepted","declined","expired","converted"]},"value":{"type":"object","properties":{"accepted":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"pipeline":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."},"converted":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","example":"1250.00","description":"Decimal string, 2 places."}},"required":["accepted","pipeline","converted"]},"avg_discount_pct":{"type":["number","null"]},"avg_first_response_minutes":{"type":["number","null"]},"avg_negotiation_days":{"type":["number","null"]},"avg_conversion_days":{"type":["number","null"]},"computed_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"}},"required":["period_start","period_end","quotes","value","avg_discount_pct","avg_first_response_minutes","avg_negotiation_days","avg_conversion_days","computed_at"]}}},"required":["object","period","currency","data"]},"CreateQuoteRequest":{"type":"object","properties":{"buyer":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"name":{"type":"string","maxLength":200},"phone":{"type":"string","maxLength":40},"company_name":{"type":"string","maxLength":200}},"required":["email"],"additionalProperties":false},"customer_id":{"type":"string","description":"Shopify Customer GID or numeric id. When the customer is a B2B company contact the quote becomes company-aware (b2b); membership is verified with Shopify."},"company_location_id":{"type":"string","description":"Preferred CompanyLocation GID when the customer belongs to several — ignored unless they're a member."},"lines":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"variant_id":{"type":"string","minLength":1,"description":"Shopify ProductVariant GID or numeric id.","example":"gid://shopify/ProductVariant/4455667788"},"quantity":{"type":"integer","minimum":1,"maximum":1000000},"requested_price":{"type":"string","pattern":"^\\d{1,10}(\\.\\d{1,2})?$","example":"12.50","description":"The buyer's target unit price (in the store currency)."},"note":{"type":"string","maxLength":1000}},"required":["variant_id","quantity"],"additionalProperties":false},{"type":"object","properties":{"custom":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000}},"required":["title"],"additionalProperties":false},"quantity":{"type":"integer","minimum":1,"maximum":1000000},"requested_price":{"type":"string","pattern":"^\\d{1,10}(\\.\\d{1,2})?$","example":"12.50"},"note":{"type":"string","maxLength":1000}},"required":["custom","quantity"],"additionalProperties":false}]},"minItems":1,"maxItems":100},"notes":{"type":"string","maxLength":5000},"po_number":{"type":"string","maxLength":100},"requested_delivery_date":{"type":"string","format":"date","example":"2026-11-01"},"shipping_address":{"$ref":"#/components/schemas/Address"},"billing_address":{"$ref":"#/components/schemas/Address"},"custom_fields":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":2000},{"type":"boolean"},{"type":"array","items":{"type":"string","maxLength":500},"maxItems":50}]}},"source_url":{"type":"string","maxLength":2000}},"required":["buyer","lines"],"additionalProperties":false},"Address":{"type":"object","properties":{"first_name":{"type":"string","maxLength":100},"last_name":{"type":"string","maxLength":100},"company":{"type":"string","maxLength":200},"address1":{"type":"string","maxLength":200},"address2":{"type":"string","maxLength":200},"city":{"type":"string","maxLength":100},"province_code":{"type":"string","maxLength":10},"country_code":{"type":"string","minLength":2,"maxLength":2},"zip":{"type":"string","maxLength":20},"phone":{"type":"string","maxLength":40}},"additionalProperties":false},"Message":{"type":"object","properties":{"object":{"type":"string","enum":["message"]},"id":{"type":"string"},"quote_id":{"type":"string"},"internal":{"type":"boolean"},"body":{"type":"string"},"created_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"}},"required":["object","id","quote_id","internal","body","created_at"]},"CreateMessageRequest":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":5000},"internal":{"type":"boolean","description":"true = merchant-only note (never emailed, never published to integrations)."}},"required":["body"],"additionalProperties":false},"SendProposalResult":{"type":"object","properties":{"object":{"type":"string","enum":["proposal_send"]},"outcome":{"type":"string","enum":["sent","awaiting_approval"],"description":"sent = emailed to the buyer · awaiting_approval = parked for internal (merchant) approval; the buyer is notified once approved."},"version_number":{"type":"integer"},"quote":{"$ref":"#/components/schemas/Quote"}},"required":["object","outcome","version_number","quote"]},"SendProposalRequest":{"type":"object","properties":{"confirm_below_floor":{"type":"boolean","description":"Send even though some lines are priced below the store's price floor (the same explicit confirmation the admin asks for)."}},"additionalProperties":false},"WebhookEndpointList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"],"description":"Always null — every endpoint is returned (max 20)."}},"required":["object","data","has_more","next_cursor"]},"WebhookEndpoint":{"type":"object","properties":{"object":{"type":"string","enum":["webhook_endpoint"]},"id":{"type":"string"},"url":{"type":"string"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled","auto_disabled"]},"source":{"type":"string","enum":["merchant","zapier","mcp"]},"created_at":{"type":"string","format":"date-time","example":"2026-09-27T10:00:00.000Z"},"secret":{"type":"string","description":"Signing secret (whsec_…) — returned ONLY when the endpoint is created."}},"required":["object","id","url","description","events","status","source","created_at"]},"CreateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2000},"events":{"type":"array","items":{"type":"string","enum":["quote.created","quote.proposal_sent","quote.countered","quote.lines_updated","quote.message_created","quote.assigned","quote.accepted","quote.partially_accepted","quote.acceptance_voided","quote.declined","quote.expired","quote.reopened","quote.closed","quote.converted","quote.invoice_sent","quote.order_completed","quote.order_cancelled","quote.order_refunded","quote.merchant_approval.requested","quote.merchant_approval.granted","quote.merchant_approval.rejected","quote.buyer_approval.requested","quote.buyer_approval.granted","quote.buyer_approval.rejected","quote.expiring_soon"]},"description":"Omit or [] for every event type."},"description":{"type":"string","maxLength":200},"source":{"type":"string","enum":["merchant","zapier","mcp"]}},"required":["url"],"additionalProperties":false}},"parameters":{}},"paths":{"/v1/ping":{"get":{"summary":"Check an API key","description":"Confirms the key works and returns its scopes. Any valid key; no scope required.","security":[{"ApiKey":[]}],"responses":{"200":{"description":"The key is valid.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ping"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/quotes":{"get":{"summary":"List quotes","description":"Newest-updated first by default. For incremental sync use `sort=updated_at` with `updated_at[gte]` set to your last watermark.","security":[{"ApiKey":[]}],"x-required-scopes":["read_quotes"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50,"description":"Default 20."},"required":false,"description":"Default 20.","name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","enum":["updated_at","-updated_at"]},"required":false,"name":"sort","in":"query"},{"schema":{"type":"string","description":"Comma-separated, e.g. proposal_sent,countered."},"required":false,"description":"Comma-separated, e.g. proposal_sent,countered.","name":"status","in":"query"},{"schema":{"type":"string","enum":["wholesale","b2b"]},"required":false,"name":"mode","in":"query"},{"schema":{"type":"string"},"required":false,"name":"updated_at[gte]","in":"query"},{"schema":{"type":"string"},"required":false,"name":"updated_at[lte]","in":"query"},{"schema":{"type":"string"},"required":false,"name":"created_at[gte]","in":"query"},{"schema":{"type":"string"},"required":false,"name":"assigned_staff_id","in":"query"},{"schema":{"type":"string"},"required":false,"name":"po_number","in":"query"},{"schema":{"type":"string","description":"Requires read_customer_data."},"required":false,"description":"Requires read_customer_data.","name":"customer_email","in":"query"}],"responses":{"200":{"description":"A page of quotes.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteList"}}}},"400":{"description":"Invalid query parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"summary":"Create a quote request","description":"Headless intake: records a buyer's quote request exactly as the Online Store does — the store's targeting rules and quote-form validation apply, automation rules run and staff are notified. Product details and catalog prices are read from Shopify (lines reference variant ids). Passing `customer_id` of a B2B company contact makes the quote company-aware.","security":[{"ApiKey":[]}],"x-required-scopes":["write_quotes"],"parameters":[{"schema":{"type":"string","maxLength":255,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h."},"required":false,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h.","name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQuoteRequest"}}}},"responses":{"201":{"description":"The new quote (status submitted).","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"400":{"description":"Invalid body (per-field errors in `errors`) or invalid JSON.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency key in use, or a limit was reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body larger than 256 KB.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Body isn't application/json.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Idempotency key reused for a different request, or the request isn't eligible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/quotes/{id}":{"get":{"summary":"Retrieve a quote","description":"Buyer personal data (the `customer` object and line notes) is included only with read_customer_data.","security":[{"ApiKey":[]}],"x-required-scopes":["read_quotes"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The quote.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such quote in this store.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/quotes/{id}/events":{"get":{"summary":"List a quote's events","description":"Published events for one quote, oldest first. Events are kept for 30 days.","security":[{"ApiKey":[]}],"x-required-scopes":["read_quotes"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"starting_after","in":"query"},{"schema":{"type":"string","description":"Comma-separated event types."},"required":false,"description":"Comma-separated event types.","name":"type","in":"query"},{"schema":{"type":"string"},"required":false,"name":"created[gte]","in":"query"},{"schema":{"type":"string"},"required":false,"name":"created[lte]","in":"query"}],"responses":{"200":{"description":"A page of events.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventList"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such quote in this store.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/events":{"get":{"summary":"List events","description":"Every published event, oldest first, for 30 days. Event ids equal the `webhook-id` of the matching webhook delivery — use this feed to recover anything your endpoint missed.","security":[{"ApiKey":[]}],"x-required-scopes":["read_quotes"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"starting_after","in":"query"},{"schema":{"type":"string","description":"Comma-separated event types."},"required":false,"description":"Comma-separated event types.","name":"type","in":"query"},{"schema":{"type":"string"},"required":false,"name":"created[gte]","in":"query"},{"schema":{"type":"string"},"required":false,"name":"created[lte]","in":"query"}],"responses":{"200":{"description":"A page of events.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventList"}}}},"400":{"description":"Invalid query parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/quotes/{id}/documents":{"get":{"summary":"List a quote's documents","description":"The quote's generated PDFs (proposal, confirmation, pro-forma invoice), newest first — metadata only. To download one, retrieve it with GET /v1/documents/{id}, which also requires read_customer_data.","security":[{"ApiKey":[]}],"x-required-scopes":["read_quotes"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The quote's documents.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentList"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such quote in this store.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/documents/{id}":{"get":{"summary":"Retrieve a document","description":"PDF metadata and a signed download link valid for 15 minutes. Requires read_customer_data as well, because the PDFs include the buyer's name, email and addresses.","security":[{"ApiKey":[]}],"x-required-scopes":["read_quotes","read_customer_data"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The document.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such document in this store.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/analytics/summary":{"get":{"summary":"Quote analytics","description":"Pre-computed period snapshots in the store's base currency.","security":[{"ApiKey":[]}],"x-required-scopes":["read_analytics"],"parameters":[{"schema":{"type":"string","enum":["day","week","month"]},"required":false,"name":"period","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":36},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Snapshots, newest first.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsSummary"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/quotes/{id}/messages":{"post":{"summary":"Post a message","description":"A merchant message on the quote thread, emailed to the buyer — or, with `internal: true`, a private note.","security":[{"ApiKey":[]}],"x-required-scopes":["write_quotes"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","maxLength":255,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h."},"required":false,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h.","name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageRequest"}}}},"responses":{"201":{"description":"The message.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Invalid body (per-field errors in `errors`) or invalid JSON.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such quote in this store.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency key in use, or a limit was reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body larger than 256 KB.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Body isn't application/json.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Idempotency key reused for a different request, or the request isn't eligible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/quotes/{id}/send-proposal":{"post":{"summary":"Send the staged proposal","description":"Sends the proposal the merchant priced and saved in QuotWay, through the same checks as the admin: the price floor (confirm with `confirm_below_floor`), approval policies (which may park it — `outcome: awaiting_approval`), then the buyer email and PDF. Pricing is never set over the API.","security":[{"ApiKey":[]}],"x-required-scopes":["write_quotes"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","maxLength":255,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h."},"required":false,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendProposalRequest"}}}},"responses":{"200":{"description":"Sent, or parked for approval.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendProposalResult"}}}},"400":{"description":"Invalid body (per-field errors in `errors`) or invalid JSON.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such quote in this store.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"No staged proposal, below the price floor (unconfirmed), not in a sendable state, or the send was interrupted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body larger than 256 KB.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Body isn't application/json.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Idempotency key reused for a different request, or the request isn't eligible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks":{"get":{"summary":"List webhook endpoints","security":[{"ApiKey":[]}],"x-required-scopes":["manage_webhooks"],"responses":{"200":{"description":"The store's endpoints.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"summary":"Create a webhook endpoint","description":"Subscribes an HTTPS endpoint to quote events (REST hooks for Zapier / automation tools). The signing secret is in this response only. Deliveries follow the Standard Webhooks spec.","security":[{"ApiKey":[]}],"x-required-scopes":["manage_webhooks"],"parameters":[{"schema":{"type":"string","maxLength":255,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h."},"required":false,"description":"Recommended. Same key + same request replays the first response (Idempotent-Replayed: true); a different request with the same key is 422; a retry while the first is still running is 409. Kept 24 h.","name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"The endpoint, including its secret.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"Invalid body (per-field errors in `errors`) or invalid JSON.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency key in use, or a limit was reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body larger than 256 KB.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Body isn't application/json.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Idempotency key reused for a different request, or the request isn't eligible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/webhooks/{id}":{"get":{"summary":"Retrieve a webhook endpoint","security":[{"ApiKey":[]}],"x-required-scopes":["manage_webhooks"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The endpoint.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"summary":"Delete a webhook endpoint","security":[{"ApiKey":[]}],"x-required-scopes":["manage_webhooks"],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted.","headers":{"X-Request-Id":{"description":"Quote this when contacting support.","schema":{"type":"string"}},"QuotWay-Version":{"description":"API version that served the request.","schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the bucket is full.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["webhook_endpoint"]},"id":{"type":"string"},"deleted":{"type":"boolean","enum":[true]}},"required":["object","id","deleted"]}}}},"401":{"description":"Missing, malformed, unknown, revoked or expired API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"The store's plan doesn't include the API (Enterprise).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"The key lacks a required scope, or the IP isn't allowlisted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"The API is temporarily unavailable (maintenance or incident) — see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"webhooks":{}}