curl --request PATCH \
--url https://api.vollna.com/v1/proposal-templates/{id} \
--header 'Content-Type: application/json' \
--header 'X-API-TOKEN: <api-key>' \
--data '
{
"name": "Web development",
"hourly_rate": {
"rate": 501,
"smart_rate_min": 501,
"smart_rate_max": 501,
"smart_rate_percent": 50,
"increase_percent": 1
},
"fixed_price": {
"price": 500002.5,
"min_price": 500002.5,
"client_budget_percent": 500
},
"ai": {
"model": "gemini-3.6-flash",
"instructions": "Write like a human",
"client_questions": "<string>",
"additional_context": "<string>",
"template_structure": true
},
"ab_testing": true,
"answers": [
{
"question": "Availability?",
"answer": "Full time"
}
],
"cover_letters": {
"variant_a": "<string>",
"variant_b": "<string>"
}
}
'import requests
url = "https://api.vollna.com/v1/proposal-templates/{id}"
payload = {
"name": "Web development",
"hourly_rate": {
"rate": 501,
"smart_rate_min": 501,
"smart_rate_max": 501,
"smart_rate_percent": 50,
"increase_percent": 1
},
"fixed_price": {
"price": 500002.5,
"min_price": 500002.5,
"client_budget_percent": 500
},
"ai": {
"model": "gemini-3.6-flash",
"instructions": "Write like a human",
"client_questions": "<string>",
"additional_context": "<string>",
"template_structure": True
},
"ab_testing": True,
"answers": [
{
"question": "Availability?",
"answer": "Full time"
}
],
"cover_letters": {
"variant_a": "<string>",
"variant_b": "<string>"
}
}
headers = {
"X-API-TOKEN": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-API-TOKEN': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Web development',
hourly_rate: {
rate: 501,
smart_rate_min: 501,
smart_rate_max: 501,
smart_rate_percent: 50,
increase_percent: 1
},
fixed_price: {price: 500002.5, min_price: 500002.5, client_budget_percent: 500},
ai: {
model: 'gemini-3.6-flash',
instructions: 'Write like a human',
client_questions: '<string>',
additional_context: '<string>',
template_structure: true
},
ab_testing: true,
answers: [{question: 'Availability?', answer: 'Full time'}],
cover_letters: {variant_a: '<string>', variant_b: '<string>'}
})
};
fetch('https://api.vollna.com/v1/proposal-templates/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vollna.com/v1/proposal-templates/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Web development',
'hourly_rate' => [
'rate' => 501,
'smart_rate_min' => 501,
'smart_rate_max' => 501,
'smart_rate_percent' => 50,
'increase_percent' => 1
],
'fixed_price' => [
'price' => 500002.5,
'min_price' => 500002.5,
'client_budget_percent' => 500
],
'ai' => [
'model' => 'gemini-3.6-flash',
'instructions' => 'Write like a human',
'client_questions' => '<string>',
'additional_context' => '<string>',
'template_structure' => true
],
'ab_testing' => true,
'answers' => [
[
'question' => 'Availability?',
'answer' => 'Full time'
]
],
'cover_letters' => [
'variant_a' => '<string>',
'variant_b' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-TOKEN: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vollna.com/v1/proposal-templates/{id}"
payload := strings.NewReader("{\n \"name\": \"Web development\",\n \"hourly_rate\": {\n \"rate\": 501,\n \"smart_rate_min\": 501,\n \"smart_rate_max\": 501,\n \"smart_rate_percent\": 50,\n \"increase_percent\": 1\n },\n \"fixed_price\": {\n \"price\": 500002.5,\n \"min_price\": 500002.5,\n \"client_budget_percent\": 500\n },\n \"ai\": {\n \"model\": \"gemini-3.6-flash\",\n \"instructions\": \"Write like a human\",\n \"client_questions\": \"<string>\",\n \"additional_context\": \"<string>\",\n \"template_structure\": true\n },\n \"ab_testing\": true,\n \"answers\": [\n {\n \"question\": \"Availability?\",\n \"answer\": \"Full time\"\n }\n ],\n \"cover_letters\": {\n \"variant_a\": \"<string>\",\n \"variant_b\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-API-TOKEN", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.vollna.com/v1/proposal-templates/{id}")
.header("X-API-TOKEN", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Web development\",\n \"hourly_rate\": {\n \"rate\": 501,\n \"smart_rate_min\": 501,\n \"smart_rate_max\": 501,\n \"smart_rate_percent\": 50,\n \"increase_percent\": 1\n },\n \"fixed_price\": {\n \"price\": 500002.5,\n \"min_price\": 500002.5,\n \"client_budget_percent\": 500\n },\n \"ai\": {\n \"model\": \"gemini-3.6-flash\",\n \"instructions\": \"Write like a human\",\n \"client_questions\": \"<string>\",\n \"additional_context\": \"<string>\",\n \"template_structure\": true\n },\n \"ab_testing\": true,\n \"answers\": [\n {\n \"question\": \"Availability?\",\n \"answer\": \"Full time\"\n }\n ],\n \"cover_letters\": {\n \"variant_a\": \"<string>\",\n \"variant_b\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vollna.com/v1/proposal-templates/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-API-TOKEN"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Web development\",\n \"hourly_rate\": {\n \"rate\": 501,\n \"smart_rate_min\": 501,\n \"smart_rate_max\": 501,\n \"smart_rate_percent\": 50,\n \"increase_percent\": 1\n },\n \"fixed_price\": {\n \"price\": 500002.5,\n \"min_price\": 500002.5,\n \"client_budget_percent\": 500\n },\n \"ai\": {\n \"model\": \"gemini-3.6-flash\",\n \"instructions\": \"Write like a human\",\n \"client_questions\": \"<string>\",\n \"additional_context\": \"<string>\",\n \"template_structure\": true\n },\n \"ab_testing\": true,\n \"answers\": [\n {\n \"question\": \"Availability?\",\n \"answer\": \"Full time\"\n }\n ],\n \"cover_letters\": {\n \"variant_a\": \"<string>\",\n \"variant_b\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 123,
"name": "Web development",
"visibility": "shared_admins",
"sender": {
"name": "John Smith",
"type": "agency",
"organization": "Acme Agency LLC"
},
"hourly_rate": {
"mode": "smart",
"rate": 50,
"smart_rate_min": 25,
"smart_rate_max": 120,
"smart_rate_percent": 98,
"rules_count": 0,
"increase_percent": null,
"increase_frequency": "never"
},
"fixed_price": {
"type": "by-job-terms",
"price": 123,
"min_price": 123,
"client_budget_percent": 123
},
"ai": {
"model": "gemini-3.6-flash",
"instructions": "Write like a human",
"client_questions": "Answer briefly",
"additional_context": "<string>",
"template_structure": true
},
"filters": [
{
"id": 123,
"name": "<string>"
}
],
"auto_bidding_setups": [
{
"id": 123,
"name": "<string>"
}
],
"ab_testing": true,
"answers": [
{
"question": "Availability?",
"answer": "Full time",
"match_type": "exact"
}
],
"attachments": [
{
"uid": "9f1c2ab34de56f7890ab12cd34ef56ab",
"name": "portfolio.pdf",
"mime_type": "application/pdf",
"size_bytes": 245760
}
],
"cover_letters": {
"variant_a": "Hi, I build web apps with Symfony and React...",
"variant_b": "<string>"
},
"created_at": "2026-08-26T10:00:00+00:00",
"updated_at": "2026-08-26T10:00:00+00:00"
}
}{
"error": "Validation failed",
"fields": {
"hourly_rate.rate": "must be a number between 3 and 999",
"ai.model": "unknown model"
}
}{
"error": "<string>"
}{
"error": "<string>"
}Update proposal template
Partial update (JSON Merge Patch): only the fields present in the body are applied, null clears or disables a field. Unknown and read-only fields are rejected. Validation runs fully before anything is written, so a failed request changes nothing
curl --request PATCH \
--url https://api.vollna.com/v1/proposal-templates/{id} \
--header 'Content-Type: application/json' \
--header 'X-API-TOKEN: <api-key>' \
--data '
{
"name": "Web development",
"hourly_rate": {
"rate": 501,
"smart_rate_min": 501,
"smart_rate_max": 501,
"smart_rate_percent": 50,
"increase_percent": 1
},
"fixed_price": {
"price": 500002.5,
"min_price": 500002.5,
"client_budget_percent": 500
},
"ai": {
"model": "gemini-3.6-flash",
"instructions": "Write like a human",
"client_questions": "<string>",
"additional_context": "<string>",
"template_structure": true
},
"ab_testing": true,
"answers": [
{
"question": "Availability?",
"answer": "Full time"
}
],
"cover_letters": {
"variant_a": "<string>",
"variant_b": "<string>"
}
}
'import requests
url = "https://api.vollna.com/v1/proposal-templates/{id}"
payload = {
"name": "Web development",
"hourly_rate": {
"rate": 501,
"smart_rate_min": 501,
"smart_rate_max": 501,
"smart_rate_percent": 50,
"increase_percent": 1
},
"fixed_price": {
"price": 500002.5,
"min_price": 500002.5,
"client_budget_percent": 500
},
"ai": {
"model": "gemini-3.6-flash",
"instructions": "Write like a human",
"client_questions": "<string>",
"additional_context": "<string>",
"template_structure": True
},
"ab_testing": True,
"answers": [
{
"question": "Availability?",
"answer": "Full time"
}
],
"cover_letters": {
"variant_a": "<string>",
"variant_b": "<string>"
}
}
headers = {
"X-API-TOKEN": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'X-API-TOKEN': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Web development',
hourly_rate: {
rate: 501,
smart_rate_min: 501,
smart_rate_max: 501,
smart_rate_percent: 50,
increase_percent: 1
},
fixed_price: {price: 500002.5, min_price: 500002.5, client_budget_percent: 500},
ai: {
model: 'gemini-3.6-flash',
instructions: 'Write like a human',
client_questions: '<string>',
additional_context: '<string>',
template_structure: true
},
ab_testing: true,
answers: [{question: 'Availability?', answer: 'Full time'}],
cover_letters: {variant_a: '<string>', variant_b: '<string>'}
})
};
fetch('https://api.vollna.com/v1/proposal-templates/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vollna.com/v1/proposal-templates/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Web development',
'hourly_rate' => [
'rate' => 501,
'smart_rate_min' => 501,
'smart_rate_max' => 501,
'smart_rate_percent' => 50,
'increase_percent' => 1
],
'fixed_price' => [
'price' => 500002.5,
'min_price' => 500002.5,
'client_budget_percent' => 500
],
'ai' => [
'model' => 'gemini-3.6-flash',
'instructions' => 'Write like a human',
'client_questions' => '<string>',
'additional_context' => '<string>',
'template_structure' => true
],
'ab_testing' => true,
'answers' => [
[
'question' => 'Availability?',
'answer' => 'Full time'
]
],
'cover_letters' => [
'variant_a' => '<string>',
'variant_b' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-TOKEN: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vollna.com/v1/proposal-templates/{id}"
payload := strings.NewReader("{\n \"name\": \"Web development\",\n \"hourly_rate\": {\n \"rate\": 501,\n \"smart_rate_min\": 501,\n \"smart_rate_max\": 501,\n \"smart_rate_percent\": 50,\n \"increase_percent\": 1\n },\n \"fixed_price\": {\n \"price\": 500002.5,\n \"min_price\": 500002.5,\n \"client_budget_percent\": 500\n },\n \"ai\": {\n \"model\": \"gemini-3.6-flash\",\n \"instructions\": \"Write like a human\",\n \"client_questions\": \"<string>\",\n \"additional_context\": \"<string>\",\n \"template_structure\": true\n },\n \"ab_testing\": true,\n \"answers\": [\n {\n \"question\": \"Availability?\",\n \"answer\": \"Full time\"\n }\n ],\n \"cover_letters\": {\n \"variant_a\": \"<string>\",\n \"variant_b\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("X-API-TOKEN", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.vollna.com/v1/proposal-templates/{id}")
.header("X-API-TOKEN", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Web development\",\n \"hourly_rate\": {\n \"rate\": 501,\n \"smart_rate_min\": 501,\n \"smart_rate_max\": 501,\n \"smart_rate_percent\": 50,\n \"increase_percent\": 1\n },\n \"fixed_price\": {\n \"price\": 500002.5,\n \"min_price\": 500002.5,\n \"client_budget_percent\": 500\n },\n \"ai\": {\n \"model\": \"gemini-3.6-flash\",\n \"instructions\": \"Write like a human\",\n \"client_questions\": \"<string>\",\n \"additional_context\": \"<string>\",\n \"template_structure\": true\n },\n \"ab_testing\": true,\n \"answers\": [\n {\n \"question\": \"Availability?\",\n \"answer\": \"Full time\"\n }\n ],\n \"cover_letters\": {\n \"variant_a\": \"<string>\",\n \"variant_b\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vollna.com/v1/proposal-templates/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["X-API-TOKEN"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Web development\",\n \"hourly_rate\": {\n \"rate\": 501,\n \"smart_rate_min\": 501,\n \"smart_rate_max\": 501,\n \"smart_rate_percent\": 50,\n \"increase_percent\": 1\n },\n \"fixed_price\": {\n \"price\": 500002.5,\n \"min_price\": 500002.5,\n \"client_budget_percent\": 500\n },\n \"ai\": {\n \"model\": \"gemini-3.6-flash\",\n \"instructions\": \"Write like a human\",\n \"client_questions\": \"<string>\",\n \"additional_context\": \"<string>\",\n \"template_structure\": true\n },\n \"ab_testing\": true,\n \"answers\": [\n {\n \"question\": \"Availability?\",\n \"answer\": \"Full time\"\n }\n ],\n \"cover_letters\": {\n \"variant_a\": \"<string>\",\n \"variant_b\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 123,
"name": "Web development",
"visibility": "shared_admins",
"sender": {
"name": "John Smith",
"type": "agency",
"organization": "Acme Agency LLC"
},
"hourly_rate": {
"mode": "smart",
"rate": 50,
"smart_rate_min": 25,
"smart_rate_max": 120,
"smart_rate_percent": 98,
"rules_count": 0,
"increase_percent": null,
"increase_frequency": "never"
},
"fixed_price": {
"type": "by-job-terms",
"price": 123,
"min_price": 123,
"client_budget_percent": 123
},
"ai": {
"model": "gemini-3.6-flash",
"instructions": "Write like a human",
"client_questions": "Answer briefly",
"additional_context": "<string>",
"template_structure": true
},
"filters": [
{
"id": 123,
"name": "<string>"
}
],
"auto_bidding_setups": [
{
"id": 123,
"name": "<string>"
}
],
"ab_testing": true,
"answers": [
{
"question": "Availability?",
"answer": "Full time",
"match_type": "exact"
}
],
"attachments": [
{
"uid": "9f1c2ab34de56f7890ab12cd34ef56ab",
"name": "portfolio.pdf",
"mime_type": "application/pdf",
"size_bytes": 245760
}
],
"cover_letters": {
"variant_a": "Hi, I build web apps with Symfony and React...",
"variant_b": "<string>"
},
"created_at": "2026-08-26T10:00:00+00:00",
"updated_at": "2026-08-26T10:00:00+00:00"
}
}{
"error": "Validation failed",
"fields": {
"hourly_rate.rate": "must be a number between 3 and 999",
"ai.model": "unknown model"
}
}{
"error": "<string>"
}{
"error": "<string>"
}Authorizations
API token for authentication
Path Parameters
Proposal template ID (from /proposal-templates)
Body
All fields optional; send only what you change. null clears or disables where noted
Non-empty; null not allowed
255"Web development"
Assign who bids with this template, from GET /proposal-senders. contractor_uid is required for agencies and not allowed for freelancer profiles. Switching an agency template to a freelancer sender makes it ineligible for auto-bidding
Show child attributes
Show child attributes
Partial update of the hourly rate block
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Replaces the whole list
50Show child attributes
Show child attributes
Partial update of the A/B slots
Show child attributes
Show child attributes
The API token acts with team admin rights; private is not available through the API
shared_view, shared_edit, shared_admins Response
Template updated; returns the same shape as GET /proposal-templates/{id}
Show child attributes
Show child attributes
Was this page helpful?