Skip to main content
Qwilr API

Quote data lifecycle

Quotes from external systems can be pushed into Qwilr, and reconciled once a proposal is accepted. This page explains how.

Overview

You can send quote data to Qwilr to have your quote represented on your Qwilr page, and when a customer accepts the quote, you can retrieve the options the customer selected within the quote as part of accepting.

Quote data can include metadata. This allows you to represent your systems identifiers on quote line items, or quote sections, in order to easily reconcile quote and fulfilment in your systems.

Sending Quote data into Qwilr pages

The Qwilr API allows you to pass quote data into a new page as part of the Saved Blocks approach to using the . Passing quote data into a Saved Quote Block will override the entirety of the quote contents. The text area before the quote, the quote currency, styles, and other block-level settings cannot be overridden programmatically.

Quote block fundamentals

Familiarise yourself with the GUI based usage of Qwilr quote blocks, as the API provides functionality that adheres to the domain model, calculations, and logical behaviours.

Example Quote blocks

Example 1 - Optional add-ons, and optional line-items

In this quote, a customer has a core cost - the first quote section - and two optional add ons. Within a few of the sections there are optional items, some with optional quantity selection. The third section is a bundle with opaque pricing, as the columns for quantity, price, and unit label are hidden.

Take a look at the page created by this JSON here.

{
"blocks": [
{
"id": "cJMrJlTWRjD4czlOPoEEwQ51y1UKNQ",
"quoteSections": [
{
"description": "First quote section. Mandatory",
"lineItems": [
{
"type": "fixedCost",
"description": "Line item 1",
"unitPrice": 200,
"unitLabel": "kg",
"quantity": 4
},
{
"type": "fixedCost",
"description": "Line item 2",
"unitPrice": 200,
"unitLabel": "meter",
"quantityRange": { "min": 3, "max": 6 },
"optional": true,
"selected": true,
"quantity": 4
}
],
"settings": { "selected": true, "selectionRequired": true }
},
{
"description": "Second quote section. Optional",
"lineItems": [
{
"type": "text",
"description": "Some text to describe why someone might want to include this section in their quote."
},
{
"type": "fixedCost",
"description": "Line item 1",
"unitPrice": 200,
"unitLabel": "bag",
"quantity": 1
},
{
"type": "fixedCost",
"description": "Line item 2",
"unitPrice": 10,
"unitLabel": "packet",
"quantity": 15,
"quantityRange": { "min": 10, "max": 50 },
"optional": true,
"selected": false
}
],
"settings": { "selected": false, "selectionRequired": false }
},
{
"description": "Third quote section",
"lineItems": [
{
"type": "fixedCost",
"description": "Line item 1",
"unitPrice": 800,
"unitLabel": "none",
"quantity": 1
},
{
"type": "fixedCost",
"description": "Line item 2",
"unitPrice": 1577,
"unitLabel": "none",
"quantity": 1
},
{
"type": "fixedCost",
"description": "Line item 3",
"unitPrice": 3500,
"unitLabel": "none",
"quantity": 1
}
],
"settings": {
"selected": false,
"selectionRequired": false,
"showUnitPrice": false,
"showQuantity": false,
"showCost": false
}
}
],
"quoteSettings": {
"selectionType": "multi"
}
}
],
"name": "Quote Block Example 1",
"published": true,
"substitutions": {
"greeting": "Quote Example 1"
},
"metadata": {}
}

Example 2 - Three alternatives, and an opaque onboarding cost

In this quote, a buyer is being offered 3 different prices for the same software license. They would need to select before signing. They have a monthly cost for an ongoing contract, a 1 year contract, and a 3 year contract. The 1 year and 3 year contracts include a discounts on all recurring costs. The final quote section is a one-off cost for onboarding.

Take a look at the page created by this JSON here.

{
"blocks": [
{
"id": "cJMrJlTWRjD4czlOPoEEwQ51y1UKNQ",
"quoteSections": [
{
"description": "First quote section. Optional",
"lineItems": [
{
"type": "text",
"description": "This is our standard monthly rate."
},
{
"type": "fixedCost",
"description": "License cost",
"unitPrice": 500,
"unitLabel": "per user, per month",
"quantity": 4,
"quantityRange": { "min": 4, "max": 20 }
},
{
"type": "fixedCost",
"description": "Support cost",
"unitPrice": 1000,
"unitLabel": "monthly",
"quantity": 1
}
],
"settings": { "selected": true, "selectionRequired": false }
},
{
"description": "Second quote section. Optional",
"lineItems": [
{
"type": "text",
"description": "If you select this option, you'll sign up for a year, and we'll provide a 10% discount."
},
{
"type": "fixedCost",
"description": "License cost",
"unitPrice": 500,
"unitLabel": "per user, per month",
"quantity": 4,
"quantityRange": { "min": 4, "max": 20 }
},
{
"type": "fixedCost",
"description": "Support cost",
"unitPrice": 1000,
"unitLabel": "yearly",
"quantity": 1
}
],
"settings": {
"selected": false,
"selectionRequired": false,
"sectionDiscount": { "type": "percentage", "amount": 10 }
}
},
{
"description": "Third quote section",
"lineItems": [
{
"type": "text",
"description": "If you select this option, you'll sign up for 3 years, and we'll provide a 15% discount."
},
{
"type": "fixedCost",
"description": "License cost",
"unitPrice": 500,
"unitLabel": "per user, per month",
"quantity": 4,
"quantityRange": { "min": 4, "max": 20 }
},
{
"type": "fixedCost",
"description": "Support cost",
"unitPrice": 1000,
"unitLabel": "per month",
"quantity": 1
}
],
"settings": {
"selected": false,
"selectionRequired": false,
"sectionDiscount": { "type": "percentage", "amount": 15 }
}
},
{
"description": "Fourth quote section",
"lineItems": [
{
"type": "text",
"description": "Set up costs are one-off."
},
{
"type": "fixedCost",
"description": "Onboarding costs",
"unitPrice": 2000,
"unitLabel": "one-off",
"quantity": 1
}
],
"settings": {
"selected": true,
"selectionRequired": true,
"showUnitPrice": false,
"showQuantity": false,
"showCost": false
}
}
],
"quoteSettings": {
"selectionType": "single"
}
}
],
"name": "Quote Block Example 2",
"published": true,
"substitutions": {
"greeting": "Quote Example 2"
},
"metadata": {}
}

Page and quote metadata

Each page, quote sections, and quote line item can have a metadata object optionally included. When included, these objects are returned as part of the webhook (page metadata only) and page GET (page, quote section, and line item).

Qwilr creates interactive quotes in which users can optionally select line items and sections, or optionally change quantities of line items. With metadata attached at each level, it's easier to reconcile what a customer selected as part of accepting a proposal.

Example 3 - Combined quote with external system metadata

In this quote, a buyer has a combined package. Three quote sections of fixed costs, with the third section having opaque costing, as price, unit label, and quantity are hidden. Metadata is present behind each quote section and line-item, but the buyer doesn't see this.

Take a look at the page created by this JSON here.

{
"blocks": [
{
"id": "cJMrJlTWRjD4czlOPoEEwQ51y1UKNQ",
"quoteSections": [
{
"description": "First quote section",
"lineItems": [
{
"type": "text",
"description": "These are the monthly costs."
},
{
"type": "fixedCost",
"description": "Monthly license cost",
"unitPrice": 150,
"unitLabel": "user",
"quantity": 5,
"metadata": { "external-line-item-id": "23fo8nwdkvi3n4v" }
},
{
"type": "fixedCost",
"description": "Support cost",
"unitPrice": 1000,
"unitLabel": "monthly",
"quantity": 1,
"metadata": { "external-line-item-id": "23r90v43ogf34ty3" }
}
],
"settings": {
"selected": true,
"selectionRequired": false,
"metadata": { "external-quote-section-id": "324g984v3f92v3" }
}
},
{
"description": "Second quote section",
"lineItems": [
{
"type": "fixedCost",
"description": "Line item 1",
"unitPrice": 1500,
"unitLabel": "day",
"quantity": 5,
"metadata": { "external-line-item-id": "09wdjcwoi2n3v3" }
},
{
"type": "fixedCost",
"description": "Line item 2",
"unitPrice": 2000,
"unitLabel": "day",
"quantity": 2,
"metadata": { "external-line-item-id": "iwuv9284cn2f09" }
},
{
"type": "fixedCost",
"description": "Line item 3",
"unitPrice": 2400,
"unitLabel": "day",
"quantity": 2,
"metadata": { "external-line-item-id": "0924uif298v528" }
}
],
"settings": {
"selected": false,
"selectionRequired": false,
"sectionDiscount": { "type": "percentage", "amount": 10 },
"metadata": { "external-quote-section-id": "90weciu24co942" }
}
},
{
"description": "Third quote section",
"lineItems": [
{
"type": "text",
"description": "Set up costs are one-off."
},
{
"type": "fixedCost",
"description": "Onboarding costs",
"unitPrice": 2000,
"unitLabel": "one-off",
"quantity": 1,
"metadata": { "external-line-item-id": "09wrcuv2098vc2" }
}
],
"settings": {
"selected": true,
"selectionRequired": true,
"showUnitPrice": false,
"showQuantity": false,
"showCost": false,
"metadata": { "external-quote-section-id": "98vcu9cv82hev" }
}
}
],
"quoteSettings": {
"selectionType": "combined"
}
}
],
"name": "Quote Block Example 3",
"published": true,
"substitutions": {
"greeting": "Quote Example 3"
},
"metadata": { "external-page-id": "98vcu9cv82hev" }
}

Page acceptance

When you set up your Qwilr integration, you can subscribe to a . This will send a short message to the subscribed URL at the time of final acceptance of that document (in the case of multiple signatories, this is when the last esignature is completed).

In this example, you can see a page GET from an accepted version of Example 1.

{
"id": "60b879a46068cf0006899488",
"name": "Quote Block Example 1 - Accepted example",
"status": "accepted",
"tags": [],
"links": {
"pdfUrl": "https://pages.qwilr.com/pdf/0ak9H2AdQ5S0",
"editorUrl": "https://app.qwilr.com/#/page/093rb4920t09j2g03294",
"publicUrl": "https://pages.qwilr.com/0ak9H2AdQ5S0"
},
"metadata": null,
"acceptance": {
"accepters": [
{
"name": "Jane Doe",
"email": "jane@test.com",
"legalEntity": "Jane Doe Ltd.",
"esigned": false,
"acceptedAt": "2021-06-04T06:19:39.035Z"
}
],
"acceptersCount": 1,
"acceptersTotal": 1,
"quote": {
"amount": 7677,
"amountExcludingTax": 7677,
"quoteSections": [
{
"selected": true,
"lineItems": [
{
"type": "fixedCost",
"quantity": 4,
"unitPrice": 200,
"selected": true,
"metadata": null
},
{
"type": "fixedCost",
"quantity": 4,
"unitPrice": 200,
"selected": true,
"metadata": null
}
],
"metadata": null
},
{
"selected": true,
"lineItems": [
{
"type": "text",
"metadata": null
},
{
"type": "fixedCost",
"quantity": 1,
"unitPrice": 200,
"selected": true,
"metadata": null
},
{
"type": "fixedCost",
"quantity": 15,
"unitPrice": 10,
"selected": false,
"metadata": null
}
],
"metadata": null
},
{
"selected": false,
"lineItems": [
{
"type": "fixedCost",
"quantity": 1,
"unitPrice": 800,
"selected": true,
"metadata": null
},
{
"type": "fixedCost",
"quantity": 1,
"unitPrice": 1577,
"selected": true,
"metadata": null
},
{
"type": "fixedCost",
"quantity": 1,
"unitPrice": 3500,
"selected": true,
"metadata": null
}
],
"metadata": null
}
]
}
}
}

When you receive the webhook, you will get your metadata object + the page ID. Complete a page GET in order to retrieve the full details of the acceptance, including the accepted quote (quantities, selected options).