Generate professional sales proposals and quotes in PDF format from your CRM data using Liquid templates. Built for sales teams and backend developers who need automated proposal generation without document complexity.
Every prospect needs a customized proposal with specific pricing, product configurations, and terms. Manual proposal creation slows down your sales cycle and creates inconsistent formatting. Building PDF generation into your CRM means dealing with complex document libraries and template management.
Send your deal data and proposal template to our API. Get back professionally formatted proposals ready for client delivery.
#Submit proposal generation request
curl --request POST \
--url https://dash.liquidtemplater.com/items/template_request \
--header 'Authorization: Bearer YOUR_BEARER_API_KEY_HERE_1234578' \
--header 'content-type: application/json' \
--data '{
"data": {
"proposal": {
"id": "PROP-2025-0847",
"date": "2025-06-20",
"valid_until": "2025-07-20",
"client": {
"company": "Acme Manufacturing",
"contact": "John Smith",
"email": "john@acme.com",
"address": "456 Industrial Blvd, Detroit, MI"
},
"items": [
{
"product": "Enterprise CRM License",
"description": "Full-featured CRM with advanced analytics",
"quantity": 50,
"unit_price": 89,
"total": 4450
},
{
"product": "Implementation Services",
"description": "Setup, training, and data migration",
"quantity": 40,
"unit_price": 150,
"total": 6000
}
],
"subtotal": 10450,
"discount": 5,
"tax_rate": 8.5,
"total": 10011.13
},
"company": {
"name": "SalesForce Pro",
"logo_url": "https://company.com/logo.png",
"address": "789 Business Ave, Austin, TX"
}
},
"template": "<proposal template content>",
"type": "pdf"
}'
#Response includes processing ID
{
"data": {
"id": "9125fdc1-a094-4464-8a5e-c5f28ee7dcca",
"result": null,
"fullfilled_on": null
}
}
#Poll for completion
curl --request GET \
--url https://dash.liquidtemplater.com/items/template_request/9125fdc1-a094-4464-8a5e-c5f28ee7dcca \
--header 'Authorization: Bearer YOUR_BEARER_API_KEY_HERE_1234578'
#When ready, get download URL
{
"data": {
"id": "9125fdc1-a094-4464-8a5e-c5f28ee7dcca",
"result": "166013e8-a767-4d1f-9502-889378a7f715",
"fullfilled_on": "2025-06-20T11:32:11"
}
}
#Download the proposal
curl 'https://dash.liquidtemplater.com/assets/166013e8-a767-4d1f-9502-889378a7f715?download=true' \
--header 'Authorization: Bearer YOUR_BEARER_API_KEY_HERE_1234578'
SALES PROPOSAL
Proposal: {{ proposal.id }}
Date: {{ proposal.date | date: "%B %d, %Y" }}
Valid Until: {{ proposal.valid_until | date: "%B %d, %Y" }}
TO:
{{ proposal.client.company }}
{{ proposal.client.contact }}
{{ proposal.client.address }}
FROM:
{{ company.name }}
{{ company.address }}
PROPOSED SOLUTION
{% for item in proposal.items %}
{{ item.product }}
{{ item.description }}
Quantity: {{ item.quantity }} × ${{ item.unit_price }} = ${{ item.total | number }}
{% endfor %}
PRICING SUMMARY
Subtotal: ${{ proposal.subtotal | number }}
{% if proposal.discount > 0 -%}
Discount ({{ proposal.discount }}%): -${{ proposal.subtotal | times: proposal.discount | divided_by: 100 | number }}
{% endif -%}
Tax ({{ proposal.tax_rate }}%): ${{ proposal.subtotal | times: proposal.tax_rate | divided_by: 100 | number }}
TOTAL: ${{ proposal.total | number }}
This proposal is valid until {{ proposal.valid_until | date: "%B %d, %Y" }}.
Product Sales Proposals
Project-Based Proposals
Subscription Proposals
//Generate proposal from CRM opportunity
async function generateProposal(opportunityId) {
const opportunity = await crm.getOpportunity(opportunityId);
const company = await settings.getCompanyInfo();
const proposalData = {
proposal: {
id: opportunity.proposalNumber,
date: new Date().toISOString().split('T')[0],
valid_until: opportunity.closeDate,
client: opportunity.account,
items: opportunity.lineItems,
subtotal: opportunity.amount,
discount: opportunity.discount || 0,
tax_rate: opportunity.taxRate || 0,
total: opportunity.totalAmount
},
company
};
const response = await fetch('https://dash.liquidtemplater.com/items/template_request', {
method: 'POST',
headers: {
'Authorization': `Bearer ${YOUR_BEARER_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: proposalData,
template: getProposalTemplate(opportunity.type),
type: 'pdf'
})
});
const { data: { id } } = await response.json();
//Poll until fullfilled_on has a value
const result = await pollForCompletion(id);
return `https://dash.liquidtemplater.com/assets/${result.data.result}?download=true`;
}
Generate proposals in the format your sales process requires:
Simply change the type parameter in your API request.
Asynchronous Processing: Proposal generation happens in the background while your sales team continues working.
Template Consistency: Ensure brand consistency across all sales materials without design overhead.
GDPR Compliant: Generated proposals stored securely in Germany for 7 days, automatically purged afterward.
Automatically send proposals to prospects using your own SMTP credentials:
{
"data": {
"proposal": {...},
"email_to": "john@acme.com",
"email_from": "sales@yourcompany.com"
},
"template": "{{proposal_template}}",
"type": "email"
}
Requires SMTP setup in your dashboard first.
CRM Workflow Automation
Quote Management
Sales teams using automated proposal generation report:
Free Tier: 100 renders/month - perfect for small sales teams Pro: €55/month for 10,000 renders + €0.005 per additional render Enterprise: Unlimited renders with dedicated infrastructure
Built by developers, for developers. No vendor lock-in, no complex setup.