> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.solvimon.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.solvimon.com/_mcp/server.

# Share, accept and convert a quote

This page shows what you do after you finalize a quote version. You share it with the customer, record the customer's decision, optionally collect a signature, and convert the accepted version into a billing subscription. Each step is available through the API and in Desk.

---

## How it works

```mermaid
stateDiagram-v2
    [*] --> DRAFT
    DRAFT --> WAITING_APPROVAL: finalize, policy matched
    DRAFT --> FINAL: finalize
    WAITING_APPROVAL --> FINAL: approved
    WAITING_APPROVAL --> DECLINED: declined
    WAITING_APPROVAL --> DRAFT: request cancelled
    FINAL --> SEND: send (API)
    FINAL --> ACCEPTED: accept
    SEND --> ACCEPTED: accept
    FINAL --> REJECTED: reject
    SEND --> REJECTED: reject
    FINAL --> SIGNATURE_REQUESTED: request signature
    ACCEPTED --> SIGNATURE_REQUESTED: request signature
    SIGNATURE_REQUESTED --> SIGNED: all recipients done
    SIGNATURE_REQUESTED --> ACCEPTED: request voided
    SIGNED --> ACCEPTED: accept
    ACCEPTED --> CLOSED: create subscription
    SIGNED --> CLOSED: create subscription
```

| Action                  | Endpoint                                           | Allowed from              |
| ----------------------- | -------------------------------------------------- | ------------------------- |
| Finalize                | `POST /v1/quote-versions/{id}/finalize`            | `DRAFT`, `DECLINED`       |
| Record as sent          | `POST /v1/quote-versions/{id}/send`                | `FINAL`, `SEND`           |
| Accept                  | `POST /v1/quote-versions/{id}/accept`              | `FINAL`, `SEND`, `SIGNED` |
| Reject                  | `POST /v1/quote-versions/{id}/reject`              | `FINAL`, `SEND`           |
| Request signature       | `POST /v1/quote-versions/{id}/request-signature`   | `FINAL`, `ACCEPTED`       |
| Convert to subscription | `POST /v1/quote-versions/{id}/create-subscription` | `ACCEPTED`, `SIGNED`      |

You can accept or reject a version one time only. A call from any other status, or after the version's `expires_at`, returns a validation error on `status` or `expires_at`.

Accepting or signing a quote in Solvimon does not create a subscription. Converting is a separate step, so you decide when billing starts. The [DocuSign integration](/integrations/e-signature/docusign) is the exception. It converts the quote after every signer signs the envelope.

---

## Finalize a quote version

Finalizing locks the version, runs your [approval policies](/platform-guides/customers-and-billing/quoting/approval-policy), and creates the customer's portal link. Call [Finalize the quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions-by-resource-id-finalize):

**`Finalize a quote version`**

```bash Finalize a quote version
curl -X POST https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/finalize \
  -H "X-API-KEY: <apiKey>"
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "quote_id": "quot_awDwHo0tYd4VZdBhe010",
  "version": 1,
  "status": "FINAL",
  "expires_at": "2026-11-30T23:59:59Z",
  "link": {
    "portal_url_id": "purl_KwDxZe0vHg5TqWBn7d1C",
    "url": "https://test.portal.solvimon.link/quote?t=..."
  },
  "invoices_info": {
    "first_invoice_summary": {
      "base_amount": { "quantity": "1000.00", "currency": "EUR" },
      "tax_amount": { "quantity": "210.00", "currency": "EUR" },
      "total_amount": { "quantity": "1210.00", "currency": "EUR" },
      "country_code": "NL"
    }
  }
}
```

Before you finalize through the API, make sure that:

* The version's subscription (type `QUOTE`) has status `ACTIVE`. Desk does this for you. Through the API, update the subscription's `status` to `ACTIVE` first. If you do not, finalize fails with a validation error on `pricing_plan_subscription_resource_id`.
* `expires_at`, if set, is still in the future.
* Solvimon can evaluate every approval rule for this quote. If it cannot, finalize returns `422`. [Check approvals before finalizing](/platform-guides/customers-and-billing/quoting/approval-policy#check-approvals-before-finalizing) to catch this first.

If an approval policy matches, the response has `status: "WAITING_APPROVAL"` and an `approval_request_id`, but no `link`. Solvimon creates the link when an approver approves the request.

`invoices_info.first_invoice_summary` holds the first invoice's amount before tax, tax and total. It is empty when the customer has no address country, because Solvimon cannot calculate tax. To see the full first invoice, call [Create a preview invoice](https://docs.solvimon.com/api-docs/transaction-api/invoices/post-invoices-preview) with the quote's subscription:

**`Preview the first invoice of a quote`**

```bash Preview the first invoice of a quote
curl -X POST https://test.api.solvimon.com/v1/invoices/preview \
  -H "X-API-KEY: <apiKey>" \
  -H "Content-Type: application/json" \
  -d '{
    "pricing_plan_subscription_id": "ppsu_HwDeeN0ueZElY7AltP1z",
    "start_at": "2026-11-01T00:00:00Z"
  }'
```

**`Response (shortened)`**

```json Response (shortened)
{
  "first_invoice": {
    "tax_total_summary": {
      "base_amount": { "quantity": "1000.00", "currency": "EUR" },
      "tax_amount": { "quantity": "210.00", "currency": "EUR" },
      "total_amount": { "quantity": "1210.00", "currency": "EUR" }
    }
  }
}
```

### Via Desk

1. Click **Finalize and publish** at the bottom of the draft quote.
2. Optionally, set **Quote version expires at**.
3. Confirm.

See [Quotes](/platform-guides/customers-and-billing/quoting#creating-a-quote).

---

## Share the quote

Share a `FINAL` version in one of two ways:

* **Portal link.** `link.url` on the quote version opens a hosted page. On that page, the customer reads the quote, downloads it and its attachments, and accepts or rejects it. The link contains a token for this customer, so send it only to the customer. Do not publish it. Quote links do not expire on their own. The version's `expires_at` controls how long the customer can act on the quote.
* **PDF.** Download the quote and send it through your own channel. A customer who only has the PDF cannot accept the quote in Solvimon. Record their decision in Desk or through the API.

Get the portal link from [Get a quote version by resource ID](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/get-quote-versions-by-resource-id):

**`Get the portal link`**

```bash Get the portal link
curl https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18 \
  -H "X-API-KEY: <apiKey>"
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "status": "FINAL",
  "link": {
    "portal_url_id": "purl_KwDxZe0vHg5TqWBn7d1C",
    "url": "https://test.portal.solvimon.link/quote?t=..."
  }
}
```

Download the PDF with [Get the quote version as PDF](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/get-quote-versions-by-resource-id-pdf):

**`Download the quote PDF`**

```bash Download the quote PDF
curl https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/pdf \
  -H "X-API-KEY: <apiKey>" \
  -o quote.pdf
```

The response body is the PDF (`application/pdf`).

If you send the quote yourself and want the version to reflect that, record it with [Send the quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions-by-resource-id-send). Solvimon stores the addresses on the action and sets `SEND`. It does not email the customer.

**`Record that the quote was sent`**

```bash Record that the quote was sent
curl -X POST https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/send \
  -H "X-API-KEY: <apiKey>" \
  -H "Content-Type: application/json" \
  -d '{
    "to_email_addresses": ["buyer@customer.com"],
    "cc_email_addresses": ["rep@yourcompany.com"]
  }'
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "status": "SEND"
}
```

### Via Desk

After you publish, the quote shows **Quote has been published** with **Download PDF** and **Copy portal URL**.

---

## Record the customer's decision

### In the customer portal

The quote page shows the content, the schedules and prices, the first-invoice total, attachments, and the expiry date ("This quote expires on …"). The customer can **Download quote**, **Accept quote** or **Reject quote**. The portal records the decision without a name or a rejection reason.

### Via API

Accept on the customer's behalf with [Accept the quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions-by-resource-id-accept), optionally with the name and role of the person who accepted:

**`Accept a quote version`**

```bash Accept a quote version
curl -X POST https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/accept \
  -H "X-API-KEY: <apiKey>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": { "first_name": "Jane", "last_name": "Doe" },
    "role": "CFO"
  }'
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "status": "ACCEPTED"
}
```

Reject with [Reject the quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions-by-resource-id-reject), optionally with a reason:

**`Reject a quote version`**

```bash Reject a quote version
curl -X POST https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/reject \
  -H "X-API-KEY: <apiKey>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": { "first_name": "Jane", "last_name": "Doe" },
    "role": "CFO",
    "reason": "Price is above budget"
  }'
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "status": "REJECTED"
}
```

A rejection also cancels the version's `QUOTE` subscription. To continue the deal, create a new version. Solvimon stores the name, role and reason on the version's `actions`.

### Via Desk

On a `FINAL` quote, Desk shows "This quote is awaiting the customer's acceptance" with **Reject** and **Accept**. **Reject** asks for a reason. **Accept** asks you to confirm the customer's details first.

---

## Collect a signature

To have the customer sign, add at least one recipient with role `SIGNER` to the version. A recipient is an existing contact of the customer, or a name and email address. Recipients with role `VIEWER` do not sign. They confirm that they reviewed the quote. Then call [Request signature for the quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions-by-resource-id-request-signature):

**`Request a signature`**

```bash Request a signature
curl -X POST https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/request-signature \
  -H "X-API-KEY: <apiKey>"
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "status": "SIGNATURE_REQUESTED"
}
```

Signers click **Sign quote** on the quote page in the portal. Viewers click **Confirm I've reviewed**. When every recipient completes this step, the version moves to `SIGNED`. You can convert a signed version directly. You do not need to accept it first.

In Desk, add signers with **Add signer**. While a signature is pending, Desk shows **Download PDF** and **Open in customer portal**. For a signature that you collected outside Solvimon, select **Mark as signed** in the **⋯** menu.

With the [DocuSign integration](/integrations/e-signature/docusign), the signature request goes out as a DocuSign envelope instead. After every signer signs, the integration accepts the quote and converts it into a subscription.

---

## Convert to a subscription

The conversion creates the subscription that bills. It copies the version's schedules and terms into a new subscription of type `BILLING`, activates it, and moves the quote version to `CLOSED`. The quoted start and end dates stay the same. Call [Create the subscription based on a approved quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions-by-resource-id-create-subscription):

**`Convert a quote version`**

```bash Convert a quote version
curl -X POST https://test.api.solvimon.com/v1/quote-versions/quve_zwDsvH0vxuCEuSCv6j18/create-subscription \
  -H "X-API-KEY: <apiKey>"
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_zwDsvH0vxuCEuSCv6j18",
  "status": "CLOSED",
  "actions": [
    {
      "type": "CREATE_SUBSCRIPTION",
      "status": "CLOSED",
      "created_at": "2026-10-04T08:30:00Z",
      "create_subscription": { "pricing_plan_subscription_id": "ppsu_TwDjXu0wLk5JqZGy7n1U" }
    }
  ]
}
```

`create_subscription.pricing_plan_subscription_id` is the new subscription.

Requirements:

* The version is `ACCEPTED` or `SIGNED`.
* The version's `expires_at` is in the future.
* The customer is `ACTIVE`. Through the API, activate a draft customer before you convert.

### Via Desk

1. On an accepted or signed quote, click **Activate subscription**. The **Convert quote to subscription** dialog lists the results:
   * The subscription becomes active and billing starts.
   * The customer becomes active.
   * You cannot revert the action.
2. Click **Convert to subscription**. Desk opens the new subscription.

You need the `PRICING_PLAN_SUBSCRIPTION.CREATE` permission to see **Activate subscription**. If you convert a version that is not the latest, Desk asks you to confirm.

---

## Create a new version

You cannot change a finalized version. To change the offer after a rejection or a declined approval, click **Create new version**. Desk creates the next version in `DRAFT` with a copy of the content, schedules and custom fields, and opens it.

Through the API, create the version with [Create a quote version](https://docs.solvimon.com/api-docs/configuration-api/quote-versions/post-quote-versions), then set up its subscription and schedules.

**`Create the next quote version`**

```bash Create the next quote version
curl -X POST https://test.api.solvimon.com/v1/quote-versions \
  -H "X-API-KEY: <apiKey>" \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "quot_awDwHo0tYd4VZdBhe010",
    "version": 2
  }'
```

**`Response (shortened)`**

```json Response (shortened)
{
  "object_type": "QUOTE_VERSION",
  "id": "quve_RwDtKa0wLmPqYbNe3c2H",
  "quote_id": "quot_awDwHo0tYd4VZdBhe010",
  "version": 2,
  "status": "DRAFT"
}
```

`version` is optional. If you set it, it must be one higher than the latest version.

---

## Edge cases

* **Expiry.** After `expires_at`, Solvimon refuses every action on the version, including accept and convert. To give the customer more time, update `expires_at` on the version.
* **Customer address.** Without an address country, the invoice preview and `invoices_info` are empty.
* **Upgrade quotes** convert the same way and also end the original subscription when the new one starts. See [Upgrade quotes](/platform-guides/customers-and-billing/quoting/upgrade-quotes).
* **Which status means "won".** For CRM automation, treat `ACCEPTED` or `SIGNED` as won and `CLOSED` as converted. Status changes arrive as `QUOTE_VERSION.UPDATED` webhooks. A signature also sends `QUOTE_VERSION.SIGNED`. The conversion sends `PRICING_PLAN_SUBSCRIPTION.CREATED` for the new subscription. See [Webhook event types](/platform-guides/for-developers/webhook-event-types).

---