Quotes API
POST /api/v1/quotes
Creates a quote. It starts as DRAFT. Requires the write:quotes scope.
Request
POST /api/v1/quotes HTTP/1.1
Host: agentlyleads.com
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"title": "Acme annual proposal",
"dealId": "cmq2deal0alk34567890",
"validUntil": "2026-12-31",
"notes": "Net 30. Freight included over 20 units.",
"lineItems": [
{ "name": "Salt blocks", "offeringId": "cmq2offr0alk34567890", "quantity": 3, "unitPrice": 12.5 },
{ "name": "Delivery", "quantity": 1, "unitPrice": 40 }
]
}Body
| Field | Required | Notes |
|---|---|---|
title | yes | Up to 200 characters |
lineItems | yes | 1 to 200 lines. Each has name, quantity and unitPrice (both zero or more), and optionally the offeringId of the product it prices |
dealId | no | The deal this quote belongs to |
contactId | no | Who the quote is for. Defaults from the deal when omitted |
companyId | no | The buying company. Defaults from the deal when omitted |
validUntil | no | YYYY-MM-DD (or a full ISO 8601 datetime) |
notes | no | Up to 5000 characters |
Every ID you pass is checked against your workspace. An ID that is not in it (including one from another workspace) is a 404 naming what was not found, and nothing is created.
The quote's prices are whatever you send. Look up current catalog prices with GET /api/v1/products first if the quote should match them.
Response (201)
{ "quote": { "id": "cmq2quot0alk34567890", "number": 12, "status": "DRAFT", "total": 77.5, "...": "..." } }Calling this twice creates two quotes.