Partner Portal

Create and send quotes

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

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.

Prerequisites

To be able to create quotes, an entity must have either the tax_id or vat_id or both specified. If an entity was initially created without tax_id and vat_id, update the entity and add these values.

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.

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 -X GET 'https://api.sandbox.monite.com/v1/vat_rates?counterpart_id=0414f...5435' \
     -H 'X-Monite-Version: 2023-06-04' \
     -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 with the type field in the request body set to quote.

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-Version: 2023-06-04' \
     -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_id": "4c6d245f-0f57-4db1-8e94-eaa6311a8e7a",
       "counterpart_vat_id_id": "782b6f0f-0177-475c-b1e4-98dc160a656f",
       "entity_vat_id_id": "cb6c1c38-fdae-48f8-8e51-2d50d116b882"
     }'

The successful 201 Created response contains the id assigned to the created quote, along with the calculated total (total_amount), subtotal (subtotal), VAT (total_vat_amount), and other information.

{
  "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",
  "subtotal": 5000,
  "line_items": [
    {
      "quantity": 5,
      "product": {
        ...
      }
    }
  ],
  "total_amount": 5900,
  "total_vat_amount": 950,
  ...
}

📘

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

Auto-calculated amounts

Monite automatically calculates the subtotal, total, and VAT amounts for the entire quote and individual line items. These amounts are included in responses from the /receivables* endpoints. You can display these amounts in your application and use them in your business logic.

  • line_items[i].total_before_vat - line item amount including the discount but excluding VAT.
  • subtotal - quote subtotal as a sum of line item subtotals. VAT and quote-level discounts are not included, but line-item discounts are included.
  • discounted_subtotal - quote subtotal after the quote-level discount. VAT is not included.
  • total_vat_amount - total VAT amount for the entire quote.
  • total_vat_amounts - a list of VAT rates used in the document, along with the calculated total VAT amounts for each rate.
  • total_withholding_tax - if withholding_tax_rate is provided, the total withholding tax is calculated as the specified percentage of the discounted_subtotal.
  • total_amount - total quote amount after all discounts and VAT. It's the sum of discounted_subtotal and total_vat_amount, minus total_withholding_tax (if any).

📘

Note

All monetary amounts are specified in minor currency units, such as cents or pence.

After creating invoices, you can download the invoice as a PDF or send it to the customer via email.

Download the quote as PDF

Monite automatically generates the PDF version of quotes. The PDF file details - URL, file size, MD5 hash, and other information - are returned in the file field of quote responses:

{
  "type": "quote",
  ...
  "file": {
    ...
    "md5": "31d1a2dd1ad3dfc39be849d70a68dac0",
    "url": "https://bucketname.s3.amazonaws.com/<random_UUID_1>/<random_UUID_2>.pdf",
    "size": 24381,
    ...
  },
  ...
}

📘

If file is returned as null, repeat the request to GET /receivables/{quote_id} after some time.

If you need just the PDF file link without the full quote details, call GET /receivables/{quote_id}/pdf_link:

curl -X GET 'https://api.sandbox.monite.com/v1/receivables/b21c80...8ad9/pdf_link' \
     -H 'X-Monite-Version: 2023-06-04' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' 

It returns the following response:

{
  "file_url": "https://bucketname.s3.amazonaws.com/<random_UUID_1>/<random_UUID_2>.pdf"
}

Here's how the PDF looks like:

📘

The PDF file is updated automatically if the quote is changed (for example, if new line items are added to a draft quote, or if the counterpart address is changed).

Customize the PDF quote

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

Verify the quote

Before a newly created quote can be issued to a counterpart, certain required information must be present on the quote. This includes information about the entity, counterpart, line items, and VAT rates on the quote. To trigger regulatory checks for a quote and check that a quote contains all required information, send a POST request to the receivables/{receivable_id}/verify endpoint as shown:

curl -X POST 'https://api.sandbox.monite.com/v1/receivables/411dcb...289b3/verify' \
     -H 'X-Monite-Version: 2023-06-04' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \

A successful response returns an object containing the missing information required on the quote. Fields with all the required information have a null value. For example, the following example shows the response for a quote without entity tax ID and counterpart tax ID information.

{
    "receivable": null,
    "entity": [
        "tax_id"
    ],
    "counterpart": [
        "tax_id"
    ],
    "products": null,
    "vat_rates": null
}

Send the quote via email

Once a draft quote has been finalized, you can send it to the counterpart via email. The quote will be attached as a PDF file to the email. You can also preview the quote's email before sending it; for more information, see Preview a quote's email.

To send a quote this, call POST /receivables/{receivable_id}/send and provide the email subject and body text. Both the subject and body texts can include variables as placeholders for quote-specific and counterpart-specific data.

curl -X POST 'https://api.sandbox.monite.com/v1/receivables/e9a25c...8c47/send' \
     -H 'X-Monite-Version: 2023-06-04' \
     -H 'X-Monite-Entity-Id: ENTITY_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "subject_text": "New quote #{quote_number}",
       "body_text": "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 {entity_email}."
     }'

📘

The subject_text and body_text fields are email template variables that represent the email subject and body. For more information, see Create and manage email templates.

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 default From email address is [email protected]. You can customize the domain part (after @) by configuring a mailbox for the entity. The "noreply" part cannot be customized at the moment.

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

📘

  • Sending a draft quote changes its status to issued. Issued quotes can no longer be edited.
  • Only quotes in the draft, issued, and accepted statuses can be sent via email. Attempting to send a quote in the deleted, expired, or declined status will return an error.

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.