> 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.

# Quote templates

Quote templates pre-fill new quotes with reusable defaults: a pricing plan, subscription terms, quote content, and attached documents. Use them to cut manual entry and keep quotes consistent across your sales and billing teams.

---

## Why this matters

If your team sends similar quotes repeatedly (same plan, same terms, same supporting documents), configuring each quote by hand is slow and error-prone. A template captures those defaults once. New quotes created from the template start pre-populated, and the sales rep only adjusts what's specific to the deal.

## What a template can define

Every field on a template is optional; a template can define as much or as little as you like. A field you don't set is omitted from the template entirely (not stored as `null`), so it leaves the corresponding quote field untouched.

| Area                  | Field                                           | Description                                                        |
| --------------------- | ----------------------------------------------- | ------------------------------------------------------------------ |
| Pricing plan schedule | `pricing_plan_schedule.pricing_plan_version_id` | The pricing plan version the quote's schedule is created with.     |
| Subscription          | `pricing_plan_subscription.billing_currency`    | Default billing currency (alphabetic currency code).               |
| Subscription          | `pricing_plan_subscription.initial_term`        | Default initial subscription term, as a period (`type` + `value`). |
| Subscription          | `pricing_plan_subscription.renewal_term`        | Default renewal term after the initial term.                       |
| Subscription          | `pricing_plan_subscription.auto_renewal`        | Whether the resulting subscription renews automatically.           |
| Quote version         | `quote_version.content`                         | Content of the initial quote version.                              |
| Quote version         | `quote_version.document_ids`                    | Documents attached to the initial quote version.                   |

Templates follow the standard resource lifecycle: they are created in `DRAFT` status, must be activated before they can be used, and can be archived when no longer needed.

## Creating a template

### Via API

Create a template with [POST /v1/quote-templates](https://docs.solvimon.com/api-docs/configuration-api/quote-templates/post-quote-templates). Only `name` and `reference` are required:

### Request

POST [https://test.api.solvimon.com/v\{version}/quote-templates](https://test.api.solvimon.com/v\{version}/quote-templates)

```curl
curl -X POST https://test.api.solvimon.com/v1/quote-templates \
     -H "X-API-KEY: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "name": "Enterprise annual",
  "reference": "enterprise-annual",
  "description": "Default quote for enterprise deals: annual term, auto-renewal.",
  "pricing_plan_subscription": {
    "billing_currency": "EUR",
    "initial_term": {
      "type": "YEAR",
      "value": 1
    },
    "renewal_term": {
      "type": "YEAR",
      "value": 1
    },
    "auto_renewal": true
  },
  "pricing_plan_schedule": {
    "pricing_plan_version_id": "ppve_gwDeep0tDRcSvkAfeN1Z"
  },
  "quote_version": {
    "document_ids": [
      "doc_TcNqw8Hji4apQ3SS8Xp2"
    ]
  }
}'
```

```python
import requests

url = "https://test.api.solvimon.com/v1/quote-templates"

payload = {
    "name": "Enterprise annual",
    "reference": "enterprise-annual",
    "description": "Default quote for enterprise deals: annual term, auto-renewal.",
    "pricing_plan_subscription": {
        "billing_currency": "EUR",
        "initial_term": {
            "type": "YEAR",
            "value": 1
        },
        "renewal_term": {
            "type": "YEAR",
            "value": 1
        },
        "auto_renewal": True
    },
    "pricing_plan_schedule": { "pricing_plan_version_id": "ppve_gwDeep0tDRcSvkAfeN1Z" },
    "quote_version": { "document_ids": ["doc_TcNqw8Hji4apQ3SS8Xp2"] }
}
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://test.api.solvimon.com/v1/quote-templates';
const options = {
  method: 'POST',
  headers: {'X-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"name":"Enterprise annual","reference":"enterprise-annual","description":"Default quote for enterprise deals: annual term, auto-renewal.","pricing_plan_subscription":{"billing_currency":"EUR","initial_term":{"type":"YEAR","value":1},"renewal_term":{"type":"YEAR","value":1},"auto_renewal":true},"pricing_plan_schedule":{"pricing_plan_version_id":"ppve_gwDeep0tDRcSvkAfeN1Z"},"quote_version":{"document_ids":["doc_TcNqw8Hji4apQ3SS8Xp2"]}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://test.api.solvimon.com/v1/quote-templates"

	payload := strings.NewReader("{\n  \"name\": \"Enterprise annual\",\n  \"reference\": \"enterprise-annual\",\n  \"description\": \"Default quote for enterprise deals: annual term, auto-renewal.\",\n  \"pricing_plan_subscription\": {\n    \"billing_currency\": \"EUR\",\n    \"initial_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"renewal_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"auto_renewal\": true\n  },\n  \"pricing_plan_schedule\": {\n    \"pricing_plan_version_id\": \"ppve_gwDeep0tDRcSvkAfeN1Z\"\n  },\n  \"quote_version\": {\n    \"document_ids\": [\n      \"doc_TcNqw8Hji4apQ3SS8Xp2\"\n    ]\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://test.api.solvimon.com/v1/quote-templates")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"Enterprise annual\",\n  \"reference\": \"enterprise-annual\",\n  \"description\": \"Default quote for enterprise deals: annual term, auto-renewal.\",\n  \"pricing_plan_subscription\": {\n    \"billing_currency\": \"EUR\",\n    \"initial_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"renewal_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"auto_renewal\": true\n  },\n  \"pricing_plan_schedule\": {\n    \"pricing_plan_version_id\": \"ppve_gwDeep0tDRcSvkAfeN1Z\"\n  },\n  \"quote_version\": {\n    \"document_ids\": [\n      \"doc_TcNqw8Hji4apQ3SS8Xp2\"\n    ]\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://test.api.solvimon.com/v1/quote-templates")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"Enterprise annual\",\n  \"reference\": \"enterprise-annual\",\n  \"description\": \"Default quote for enterprise deals: annual term, auto-renewal.\",\n  \"pricing_plan_subscription\": {\n    \"billing_currency\": \"EUR\",\n    \"initial_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"renewal_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"auto_renewal\": true\n  },\n  \"pricing_plan_schedule\": {\n    \"pricing_plan_version_id\": \"ppve_gwDeep0tDRcSvkAfeN1Z\"\n  },\n  \"quote_version\": {\n    \"document_ids\": [\n      \"doc_TcNqw8Hji4apQ3SS8Xp2\"\n    ]\n  }\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://test.api.solvimon.com/v1/quote-templates', [
  'body' => '{
  "name": "Enterprise annual",
  "reference": "enterprise-annual",
  "description": "Default quote for enterprise deals: annual term, auto-renewal.",
  "pricing_plan_subscription": {
    "billing_currency": "EUR",
    "initial_term": {
      "type": "YEAR",
      "value": 1
    },
    "renewal_term": {
      "type": "YEAR",
      "value": 1
    },
    "auto_renewal": true
  },
  "pricing_plan_schedule": {
    "pricing_plan_version_id": "ppve_gwDeep0tDRcSvkAfeN1Z"
  },
  "quote_version": {
    "document_ids": [
      "doc_TcNqw8Hji4apQ3SS8Xp2"
    ]
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://test.api.solvimon.com/v1/quote-templates");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"Enterprise annual\",\n  \"reference\": \"enterprise-annual\",\n  \"description\": \"Default quote for enterprise deals: annual term, auto-renewal.\",\n  \"pricing_plan_subscription\": {\n    \"billing_currency\": \"EUR\",\n    \"initial_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"renewal_term\": {\n      \"type\": \"YEAR\",\n      \"value\": 1\n    },\n    \"auto_renewal\": true\n  },\n  \"pricing_plan_schedule\": {\n    \"pricing_plan_version_id\": \"ppve_gwDeep0tDRcSvkAfeN1Z\"\n  },\n  \"quote_version\": {\n    \"document_ids\": [\n      \"doc_TcNqw8Hji4apQ3SS8Xp2\"\n    ]\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "name": "Enterprise annual",
  "reference": "enterprise-annual",
  "description": "Default quote for enterprise deals: annual term, auto-renewal.",
  "pricing_plan_subscription": [
    "billing_currency": "EUR",
    "initial_term": [
      "type": "YEAR",
      "value": 1
    ],
    "renewal_term": [
      "type": "YEAR",
      "value": 1
    ],
    "auto_renewal": true
  ],
  "pricing_plan_schedule": ["pricing_plan_version_id": "ppve_gwDeep0tDRcSvkAfeN1Z"],
  "quote_version": ["document_ids": ["doc_TcNqw8Hji4apQ3SS8Xp2"]]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://test.api.solvimon.com/v1/quote-templates")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Response (201)

```json
{
  "object_type": "QUOTE_TEMPLATE",
  "id": "qute_UdPrx9Jkj5bqR4RR9Yq3",
  "name": "Enterprise annual",
  "reference": "enterprise-annual",
  "description": "Default quote for enterprise deals: annual term, auto-renewal.",
  "status": "DRAFT",
  "pricing_plan_subscription": {
    "billing_currency": "EUR",
    "initial_term": {
      "type": "YEAR",
      "value": 1
    },
    "renewal_term": {
      "type": "YEAR",
      "value": 1
    },
    "auto_renewal": true
  },
  "pricing_plan_schedule": {
    "pricing_plan_version_id": "ppve_gwDeep0tDRcSvkAfeN1Z"
  },
  "quote_version": {
    "document_ids": [
      "doc_TcNqw8Hji4apQ3SS8Xp2"
    ]
  },
  "created_at": "2026-07-02T09:15:00Z",
  "updated_at": "2026-07-02T09:15:00Z"
}
```

The template is created in `DRAFT` status. Activate it with [POST /v1/quote-templates/\{ref}/activate](https://docs.solvimon.com/api-docs/configuration-api/quote-templates/post-quote-templates-by-resource-id-or-reference-activate) before using it:

### Request

POST [https://test.api.solvimon.com/v\{version}/quote-templates/\{resourceIdOrReference}/activate](https://test.api.solvimon.com/v\{version}/quote-templates/\{resourceIdOrReference}/activate)

```curl
curl -X POST https://test.api.solvimon.com/v1/quote-templates//activate \
     -H "X-API-KEY: <apiKey>"
```

```python
import requests

url = "https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate"

headers = {"X-API-KEY": "<apiKey>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate';
const options = {method: 'POST', headers: {'X-API-KEY': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("X-API-KEY", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate")
  .header("X-API-KEY", "<apiKey>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate', [
  'headers' => [
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["X-API-KEY": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://test.api.solvimon.com/v1/quote-templates/:resourceIdOrReference/activate")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

To change a template later, use [PATCH /v1/quote-templates/\{ref}](https://docs.solvimon.com/api-docs/configuration-api/quote-templates/patch-quote-templates-by-resource-id-or-reference). To retire one, use [POST /v1/quote-templates/\{ref}/archive](https://docs.solvimon.com/api-docs/configuration-api/quote-templates/post-quote-templates-by-resource-id-or-reference-archive). Both accept the resource ID or your own reference.

### Via Desk

Open the quote template settings in the quote configuration section of Desk and fill in any of the fields above: optionally select a pricing plan version, set the subscription defaults, write the quote version content in the content editor, and attach documents. When you save, only the fields you set are stored; re-opening the template loads the saved values back into the form.

## Using a template when creating a quote

Pass the template's ID as `template_id` when creating a quote with [POST /v1/quotes](https://docs.solvimon.com/api-docs/configuration-api/quotes/post-quotes). The quote starts pre-populated with the template's pricing plan, subscription terms, content and attachments, all of which can be adjusted before the quote is sent:

### Request

POST [https://test.api.solvimon.com/v\{version}/quotes](https://test.api.solvimon.com/v\{version}/quotes)

```curl
curl -X POST https://test.api.solvimon.com/v1/quotes \
     -H "X-API-KEY: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "customer_id": "cust_AbD3DqausjOYiMNDZY11F",
  "owner_user_id": "user_VeQsy1Klk6crS5QQ1Zr4",
  "template_id": "qute_UdPrx9Jkj5bqR4RR9Yq3"
}'
```

```python
import requests

url = "https://test.api.solvimon.com/v1/quotes"

payload = {
    "customer_id": "cust_AbD3DqausjOYiMNDZY11F",
    "owner_user_id": "user_VeQsy1Klk6crS5QQ1Zr4",
    "template_id": "qute_UdPrx9Jkj5bqR4RR9Yq3"
}
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://test.api.solvimon.com/v1/quotes';
const options = {
  method: 'POST',
  headers: {'X-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"customer_id":"cust_AbD3DqausjOYiMNDZY11F","owner_user_id":"user_VeQsy1Klk6crS5QQ1Zr4","template_id":"qute_UdPrx9Jkj5bqR4RR9Yq3"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://test.api.solvimon.com/v1/quotes"

	payload := strings.NewReader("{\n  \"customer_id\": \"cust_AbD3DqausjOYiMNDZY11F\",\n  \"owner_user_id\": \"user_VeQsy1Klk6crS5QQ1Zr4\",\n  \"template_id\": \"qute_UdPrx9Jkj5bqR4RR9Yq3\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://test.api.solvimon.com/v1/quotes")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"customer_id\": \"cust_AbD3DqausjOYiMNDZY11F\",\n  \"owner_user_id\": \"user_VeQsy1Klk6crS5QQ1Zr4\",\n  \"template_id\": \"qute_UdPrx9Jkj5bqR4RR9Yq3\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://test.api.solvimon.com/v1/quotes")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"customer_id\": \"cust_AbD3DqausjOYiMNDZY11F\",\n  \"owner_user_id\": \"user_VeQsy1Klk6crS5QQ1Zr4\",\n  \"template_id\": \"qute_UdPrx9Jkj5bqR4RR9Yq3\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://test.api.solvimon.com/v1/quotes', [
  'body' => '{
  "customer_id": "cust_AbD3DqausjOYiMNDZY11F",
  "owner_user_id": "user_VeQsy1Klk6crS5QQ1Zr4",
  "template_id": "qute_UdPrx9Jkj5bqR4RR9Yq3"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://test.api.solvimon.com/v1/quotes");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"customer_id\": \"cust_AbD3DqausjOYiMNDZY11F\",\n  \"owner_user_id\": \"user_VeQsy1Klk6crS5QQ1Zr4\",\n  \"template_id\": \"qute_UdPrx9Jkj5bqR4RR9Yq3\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "customer_id": "cust_AbD3DqausjOYiMNDZY11F",
  "owner_user_id": "user_VeQsy1Klk6crS5QQ1Zr4",
  "template_id": "qute_UdPrx9Jkj5bqR4RR9Yq3"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://test.api.solvimon.com/v1/quotes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Response (201)

```json
{
  "object_type": "QUOTE",
  "id": "quot_WfRtz2Lml7dsT6PP2As5",
  "created_at": "2026-07-02T09:20:00Z",
  "updated_at": "2026-07-02T09:20:00Z",
  "status": "DRAFT",
  "customer_id": "cust_AbD3DqausjOYiMNDZY11F",
  "owner_user_id": "user_VeQsy1Klk6crS5QQ1Zr4",
  "quote_version_infos": [
    {
      "version": 1,
      "id": "quve_XgSua3Mnm8etU7NN3Bt6",
      "status": "DRAFT",
      "pricing_plan_subscription_id": "ppsu_YhTvb4Non9fuV8MM4Cu7"
    }
  ],
  "template_id": "qute_UdPrx9Jkj5bqR4RR9Yq3"
}
```

In Desk, select the template in the quote creation form to pre-fill it the same way.

> **Note**
>
> A template only sets the starting values of a quote. Editing a template later does not change quotes already created from it.

## Attachments

Documents listed in `quote_version.document_ids` are carried onto the initial version of every quote created from the template. Use this for recurring supporting documents, such as standard terms or product sheets, so they don't have to be attached by hand each time.

## Edge cases

* Only `ACTIVE` templates can be used to create quotes. A `DRAFT` template must be activated first; an `ARCHIVED` template can no longer be selected.
* All defaulting fields are optional. A template that only sets, say, a billing currency leaves everything else for the rep to fill in.
* If [default subscription settings](/platform-guides/customers-and-billing/quotes#pre-requisites) are also configured in the Settings menu, the template's values take precedence for quotes created from it.

---

See also: [Quotes](/platform-guides/customers-and-billing/quotes), [Approval policy](/platform-guides/customers-and-billing/quotes/approval-policy) and [Subscriptions](/platform-guides/customers-and-billing/subscriptions).