Manage proformas
A proforma is a preliminary document sent to a customer before a sale is confirmed. It outlines the expected cost of goods or services and gives the customer a chance to review and accept or decline the offer. Once accepted, a proforma can be converted directly into an invoice.
Proformas are also useful as invoice drafts. They can be freely updated or declined before you commit to converting them into a final, uneditable invoice.
You can find the full reference for all proforma operations in our API docs.
Lifecycle of a proforma
A proforma moves through the following states:
| State | Description |
|---|---|
outstanding | Awaiting a response from the customer (default). |
late | The valid_until date has passed with no response. |
accepted | The customer agreed to the proforma. |
declined | The customer rejected the proforma. |
invoiced | The proforma has been converted into an invoice. |
Create a proforma
Send a POST request to /proformas with the customer and line item details (more details here):
curl -u YOUR_API_KEY:x \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contact": {
"first_name": "Alex",
"last_name": "Wick",
"email": "[email protected]",
"street_line_1": "67 Church Lane",
"city": "London",
"postal_code": "E94 7RT",
"country": "GB"
},
"currency": "GBP",
"subject": "SaaS subscription — Q3 2025",
"valid_until": "2025-07-31",
"items": [
{
"description": "Professional Plan",
"quantity": 1,
"unit_price_cents": 9900,
"tax_1_transaction_type": "saas",
"tax_1_country": "GB"
}
],
"notes": "Prices are exclusive of VAT where applicable.",
"po_number": "PO-2025-001"
}' \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas.json'
A successful request returns a 201 Created response with the new proforma object:
{
"id": 92732431,
"number": "E-00001",
"state": "outstanding",
"issue_date": "2025-06-27",
"valid_until": "2025-07-31",
"currency": "GBP",
"subject": "SaaS subscription — Q3 2025",
"contact": {
"id": 229575,
"full_name": "Alex Wick"
},
"items": [
{
"description": "Professional Plan",
"quantity": 1.0,
"subtotal_cents": 9900
}
],
"subtotal_cents": 9900,
"discount_cents": 0,
"total_cents": 11880,
"taxes": [
{
"name": "VAT",
"rate": 20.0,
"amount_cents": 1980
}
],
"pdf": "https://quadernoapp.com/estimate/abc123.pdf",
"permalink": "https://quadernoapp.com/estimate/abc123",
"url": "https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431.json"
}
The pdf and permalink fields give you direct links to share the document with your customer.
Retrieve a proforma
To fetch an existing proforma by its ID (more details here):
curl -u YOUR_API_KEY:x \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431.json'
List proformas
Retrieve a paginated list of all proformas, sorted by creation date (newest first) (more details here):
curl -u YOUR_API_KEY:x \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas.json'
You can narrow the results using query parameters:
| Parameter | Description | Example |
|---|---|---|
q | Search by proforma number, customer name, or PO number. | q=E-00001 |
date | Filter by issue date range (YYYY-MM-DD,YYYY-MM-DD). | date=2025-01-01,2025-12-31 |
state | Filter by state: outstanding, accepted, declined, invoiced, late. | state=outstanding |
contact | Filter by customer ID. | contact=229575 |
curl -u YOUR_API_KEY:x \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas.json?state=outstanding&date=2025-01-01,2025-12-31'
Update a proforma
You can update a proforma as long as it is in outstanding or late state. Accepted and invoiced proformas cannot be modified (more details here):
curl -u YOUR_API_KEY:x \
-H 'Content-Type: application/json' \
-X PUT \
-d '{
"valid_until": "2025-08-31",
"notes": "Updated payment terms: net 30 days."
}' \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431.json'
Deliver a proforma
Send the proforma to your customer via email (more details here):
curl -u YOUR_API_KEY:x \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431/deliver.json'
Quaderno will email the proforma to the address on file for the contact. You can check the deliveries field in the proforma object to see the delivery history.
Manage the proforma response
Once you have delivered the proforma, you can update its state based on your customer's response.
Accept
Mark a proforma as accepted by the customer. Only proformas in outstanding or late state can be accepted (more details here):
curl -u YOUR_API_KEY:x \
-X PUT \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431/accept.json'
Decline
Mark a proforma as declined by the customer. Only proformas in outstanding or late state can be declined (more details here):
curl -u YOUR_API_KEY:x \
-X PUT \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431/decline.json'
Revert
Revert a proforma back to outstanding from accepted or declined. This is useful when you need to renegotiate terms. Invoiced proformas cannot be reverted (more details here):
curl -u YOUR_API_KEY:x \
-X PUT \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431/revert.json'
Convert a proforma into an invoice
Once a proforma is accepted, you can convert it into a final invoice. The proforma transitions to invoiced and a new invoice object is returned (more details here):
curl -u YOUR_API_KEY:x \
-X PUT \
'https://ACCOUNT_NAME.quadernoapp.com/api/proformas/92732431/convert.json'
The response will be the newly created invoice, ready to send to your customer.