Create and send quotes

Learn how to create a quote and send a formal offer.

Overview

A quote is a formal offer that details how much a product or service will cost.

Quotes are similar to invoices. The difference is that a quote is given to a potential customer before they decide to purchase, whereas an invoice is issued after the delivery of products or services to the customer.

Quotes have an expiry date by which the quote should be accepted or declined.

Create a quote

A typical quote workflow includes the following steps:

  1. Create a counterpart that represents the customer.
  2. Create one or more products to be listed in the quote.
  3. Get the applicable VAT rates based on the entity's country and the counterpart's country, and choose the rates for the products that will be listed in the quote.
  4. Create the quote.
  5. Download a PDF of the created quote. (Optional)
  6. Send the quote via email.
  7. Create an invoice based on the quote. (Optional)

1. Create a counterpart

The counterpart represents the customer (organization or individual) purchasing your products or services.

Learn how to create counterparts.

2. Create a product

The products to be listed in the quote must also be created in advance, as well as their respective measure units.

Learn how to create products and measure units.

As an example, here is a representation of a sample t-shirt product:

{
  "id": "8755c86a-d630-4920-b6fd-fd2917d87dfb",
  "name": "T-shirt",
  "type": "product",
  "description": "A black cotton t-shirt, medium size",
  "price": {
    "currency": "EUR",
    "value": 1000  // 10 Euro
  },
  "measure_unit_id": "256560f1-8d09-4d21-aadf-45b33e4b0660",
  "smallest_amount": 1
}

The associated measure unit is "pieces" (items):

{
  "id": "256560f1-8d09-4d21-aadf-45b33e4b0660",
  "name": "pcs",
  "description": "pieces",
  ...
}

3. Get VAT rates

A quote must specify VAT rates for its line items, even if the VAT is 0%. You can call GET /vat_rates?counterpart_id={id} to get the possible VAT rates for sales to the given counterpart:

curl 'https://api.sandbox.monite.com/v1/vat_rates?counterpart_id=0414f...5435' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN'

The response includes the possible VAT rates (as a percentage multiplied by 100) and their IDs. Store the IDs somewhere as you will need them later.

{
  "data": [
    {
      "id": "a39a2ec3-765d-4f75-9a17-585a5d22509d",
      ...
      "value": 0,
      "country": "DE"
    },
    {
      "id": "51cefc6c-9f82-484e-ae6a-a3a89b507bea",
      ...
      "value": 700,
      "country": "DE"
    },
    ...
  ]
}

Learn more about VAT rates.

4. Create the quote

Once the counterpart and products have been created, you can create the quote for a given counterpart by calling POST /receivables.

The request body must contain the counterpart ID, line items (products, their quantities, and VAT rates), and quote expiration date, among other information. The subtotal, total, and VAT amount are not specified in the request - they will be calculated automatically based on the product price, quantity, and VAT rates.

The example below creates a quote for five items of a product:

curl -X POST 'https://api.sandbox.monite.com/v1/receivables' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "type": "quote",
       "counterpart_id": "0414f84c-b039-4203-b09b-e42b49245435",
       "expiry_date": "2022-06-01",
       "currency": "EUR",
       "line_items": [
         {
           "product_id": "8755c86a-d630-4920-b6fd-fd2917d87dfb",
           "quantity": 5,
           "vat_rate_id": "479155c3-0995-4689-a3cf-7482ea5132a9"
         }
       ],
       "vat_exempt": false,
       "entity_bank_account": {
         "bank_name": "Omega Bank",
         "iban": "9128309180391",
         "bic": "18239012"
       }
     }'

The successful 201 Created response contains the id assigned to the created quote, along with the calculated subtotal (total_amount), VAT (total_vat_amount), and other information. The total price can be calculated as a sum of total_amount and total_vat_amount.

{
  "type": "quote",
  "expiry_date": "2022-06-01",
  "id": "e9a25ceb-003d-4c82-9e90-5d568ccd8c47",
  "created_at": "2022-05-04T09:12:53.875094+00:00",
  "updated_at": "2022-05-04T09:12:53.875103+00:00",
  "currency": "EUR",
  "total_amount": 5000,
  "line_items": [
    {
      "quantity": 5,
      "product": {
        ...
      }
    }
  ],
  "total_vat_amount": "950",
  ...
}

📘

For the complete list of quote data fields and their descriptions, refer to the /receivables endpoint.

5. Download the quote as PDF

After creating a quote, you can generate a PDF file containing the quote information that can be emailed to the customer. To do this, call GET /receivables/{quote_id}/pdf_link:

curl 'https://api.sandbox.monite.com/v1/receivables/e9a25c...8c47/pdf_link' \
  -H 'X-Monite-Entity-Id: ENTITY_ID' \
  -H 'Authorization: Bearer ACCESS_TOKEN' 

The response contains a string with the link to download the generated PDF file:

"https://<subdomain>.s3.amazonaws.com/<unique_id>"

This link is also saved to the file_url property of the Receivable object that corresponds to this quote.

The generated PDF quote looks similar to this:

📘

The PDF file is not updated automatically if the quote is changed (for example, if new line items are added, or if the counterpart address is changed). To re-generate the PDF file after quote changes, call GET /receivables/{quote_id}/pdf_link again.

Customize the PDF quote

Monite provides several built-in PDF templates for quotes. The preferred template can be set in the entity settings.

6. Send the quote via email

Once a draft quote has been prepared, you can send it to the customer via email. To do this, call POST /receivables/{quote_id}/send and provide the email subject and body templates. The quote will be attached as a PDF file to the email.

curl -X POST 'https://api.sandbox.monite.com/v1/receivables/e9a25c...8c47/send' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "subject": "New quote #{quote_number}",
       "body": "Dear {contact_name},\n\nThank you for requesting a quote for your project. We are happy to provide you with our quote #{quote_number}!\n\nIf you have any questions, please don't hesitate to contact us at {company_email}."
     }'

The To email address is taken from the Counterpart object associated with the quote. This address is also returned in the counterpart_contact.email field of the Receivable object that represents the quote.

The From email address is [email protected]<entity_name>.monite.com (currently not customizable).

The {variables} in the email content will be substituted with the corresponding values from the quote data and counterpart data. The supported variables are:

  • {quote_number} - the document_id value of the Receivable object that represents the quote.
  • {contact_name} - the counterpart name (either the company name or an individual's name).
  • {company_email} - the email address of the entity that issued this quote.

A 200 OK response from POST /receivables/{quote_id}/send means the email was successfully sent from the Monite email server.

Sending a quote changes its status from draft to issued. Issued quotes can no longer be edited.

Resend the quote

To resend an already issued quote, you can call POST /receivables/{quote_id}/send again, optionally with different subject_text and body_text templates.

Resending a quote does not change its status.

7. Accept or decline the quote

If the customer accepted the quote, call POST /receivables/{quote_id}/accept to mark the quote as accepted. Note that this request requires an empty object {} in the request body.

curl -X POST 'https://api.sandbox.monite.com/v1/receivables/e9a25c...8c47/accept' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{}'

If the customer declined the quote, call POST /receivables/{quote_id}/decline to mark the quote as declined. As a best practice, customers should provide a reason why they declined the quote. This reason can be specified in the comment field in the request body:

curl -X POST 'https://api.sandbox.monite.com/v1/receivables/e9a25c...8c47/decline' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{"comment": "Thanks for the quote, but we decided to go with another vendor."}'

7. Create an invoice based on the quote

If the customer accepted the quote, you can create an invoice based on this quote after the goods or services have been delivered. Invoices can be created from quotes in the draft, issued, and accepted states.

To create an invoice from a quote, call POST /receivables and provide the quote ID in the based_on field in the request body:

curl -X POST 'https://api.sandbox.monite.com/v1/receivables' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "type": "invoice",
       "based_on": "e9a25ceb-003d-4c82-9e90-5d568ccd8c47"
     }'

This creates a new draft invoice with a copy of the quote data (that is, with the same line items and counterpart). The ID and document number of the original quote are saved in the based_on and based_on_document_id properties, respectively.

{
  "type": "invoice",
  "id": "b21c80f9-18c0-40ce-be6b-89ddcc4d8ad9",
  "created_at": "2022-05-19T06:04:29.499753+00:00",
  "updated_at": "2022-05-19T06:04:30.976539+00:00",
  "currency": "EUR",
  "total_amount": 5000,
  "line_items": [ ... ],
  ...
  "status": "draft",
  "based_on": "e9a25ceb-003d-4c82-9e90-5d568ccd8c47",
  "based_on_document_id": "#receivable--00015",
  "payment_terms": null
}

Next, add payment terms to the created invoice. The payment terms define the invoice due date and, optionally, early payment discounts.

curl -X PATCH 'https://api.sandbox.monite.com/v1/receivables/b21c80...8ad9' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "invoice": {
         "payment_terms_id": "411d9079-02af-476d-8723-4789882e01c3"
       }
     }'

The invoice due date is calculated automatically based on the creation date and payment terms and is returned in the payment_terms.term_final.end_date property in the response.

{
  "type": "invoice",
  "id": "b21c80f9-18c0-40ce-be6b-89ddcc4d8ad9",
  "created_at": "2022-05-19T06:04:29.499753+00:00",
  ...
  "payment_terms": {
    "id": "411d9079-02af-476d-8723-4789882e01c3",
    "name": "Net 30",
    "description": "The payment is due within 30 days after the invoice issue date.",
    "term_final": {
      "number_of_days": 30,
      "end_date": "2022-06-18"
    }
  }
}

Next, you can download the invoice as PDF and send it to the customer via email.

List all quotes

To get a list of all quotes generated by an entity, call GET /receivables?type=quote:

curl 'https://api.sandbox.monite.com/v1/receivables?type=quote' \
  -H 'X-Monite-Entity-Id: ENTITY_ID' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

You can sort and filter the results by the amount, counterpart name, and other fields. For the full list of available sort and filter parameters, see the description of the GET /receivables endpoint.

Some examples:

  • GET /receivables?type=quote&counterpart_name=Acme%20Inc. - get all quotes issued to Acme Inc.
  • GET /receivables?type=quote&amount__gte=15000 - get all quotes where the total amount is €150 or more.
  • GET /receivables?type=quote&status**in=draft&status**in=issued - get all draft and issued quotes.
  • GET /receivables?type=quote&created_at__gte=2022-01-01T00%3A00%3A00 - get all quotes created on or after January 1, 2022.

Retrieve a quote

To get information about a specific quote, call GET /receivables/{receivable_id} and provide the quote ID.

Find invoices created from a quote

To check if there are invoices created from a specific quote, call GET /receivables?based_on=QUOTE_ID:

curl 'https://api.sandbox.monite.com/v1/receivables?based_on=e9a25ceb-003d-4c82-9e90-5d568ccd8c47' \
  -H 'X-Monite-Entity-Id: ENTITY_ID' \
  -H 'Authorization: Bearer ACCESS_TOKEN'

The data array in the response contains a list of related invoices, if any:

{
  "data": [
    {
      "type": "invoice",
      "id": "b21c80f9-18c0-40ce-be6b-89ddcc4d8ad9",
      ...
    }
  ],
  "prev_pagination_token": null,
  "next_pagination_token": null
}

Did this page help you?