Quotes
A quote (crm_quotes) is a versioned sales offer with line items, VAT, and public accept-flow. Scopes: sales.quotes.read / sales.quotes.write / sales.quotes.delete.
Endpoints
/api/workspace/v1/quotes/api/workspace/v1/quotes/{id}/api/workspace/v1/quotes/api/workspace/v1/quotes/{id} (draft only)/api/workspace/v1/quotes/{id}/send/api/workspace/v1/quotes/{id}/cancel/api/workspace/v1/quotes/{id}/api/workspace/v1/quotes/{id}/restore/api/workspace/v1/quotes/bulk-deleteThe quote object
| Field | Type | Description |
|---|---|---|
| crm_contact_id* | integer | Contact the quote is addressed to (required on create) |
| crm_deal_id | integer | Optional linked CRM deal |
| lines* | array | 1-100 line items — see line schema below |
| notes | string | Free-form notes shown on the quote PDF (<= 5000 chars) |
| valid_until_days | integer | Validity window in days (1-365, default 30) |
| discount_amount | number | Absolute discount amount (before VAT) |
| discount_reason | string | Short reason surfaced on the quote |
| manual_label | string | Optional label (e.g. project reference) |
| reference | string | Free-form PO / reference number |
| currency | string(3) | ISO 4217 (defaults to workspace currency) |
| status | enum | draft | sent | accepted | declined | expired | converted | cancelled | superseded (read-only) |
The line item
| Field | Type | Description |
|---|---|---|
| description* | string | 1-500 chars |
| quantity* | number | Positive quantity |
| unit_price* | number | Non-negative unit price |
| vat_rate | number | VAT percentage 0-100 (default 21) |
| sort_order | integer | Display order (default insert order) |
Create a draft quote
Quotes are created in draft status. Totals (subtotal, VAT, total) are calculated server-side from the lines and returned in the response.
curl "https://app.staffifyai.com/api/workspace/v1/quotes" \
-X POST \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"crm_contact_id": 1893,
"crm_deal_id": 1024,
"notes": "Approved after Q4 kick-off call.",
"valid_until_days": 14,
"lines": [
{ "description": "AI Voice Agent — starter tier", "quantity": 1, "unit_price": 499.00, "vat_rate": 21 },
{ "description": "Onboarding + setup", "quantity": 1, "unit_price": 299.00, "vat_rate": 21 }
]
}'Send a quote to the customer
POST /quotes/{id}/send transitions draft → sent, generates a public accept URL (returned as public_url), and fires the quote.sent webhook.
curl -X POST "https://app.staffifyai.com/api/workspace/v1/quotes/551/send" \ -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \ -H "Idempotency-Key: send-551-2026-09-16"
Cancel a sent quote
POST /quotes/{id}/cancel transitions sent → cancelled. Only sent quotes can be cancelled — draft quotes should be deleted instead. Fires quote.cancelled.
curl -X POST "https://app.staffifyai.com/api/workspace/v1/quotes/551/cancel" \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Customer withdrew after budget cut." }'List quotes
Standard page/limit pagination. Filter by status, deal_id, contact_id. Recycle-bin filter via deleted=true | false | any.
curl "https://app.staffifyai.com/api/workspace/v1/quotes?status=sent&limit=50" \ -H "Authorization: Bearer sfy_wsp_live_YOUR_KEY"
Update a draft quote
Only draft quotes can be edited. Once sent, use /cancel + create a new version. Passing lines replaces the full set (all-or-nothing).
curl -X PATCH "https://app.staffifyai.com/api/workspace/v1/quotes/551" \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "discount_amount": 50, "discount_reason": "First-month promo" }'Delete / restore / bulk-delete
Soft-delete moves a quote to the recycle bin for 30 days. Only draft quotes can be soft-deleted — sent quotes must be cancelled first. Requires the separate sales.quotes.delete scope.
# Soft-delete
curl -X DELETE "https://app.staffifyai.com/api/workspace/v1/quotes/551" \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY"
# Restore
curl -X POST "https://app.staffifyai.com/api/workspace/v1/quotes/551/restore" \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY"
# Bulk-delete (max 500 ids)
curl -X POST "https://app.staffifyai.com/api/workspace/v1/quotes/bulk-delete" \
-H "Authorization: Bearer sfy_wsp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "ids": [551, 552, 553] }'Webhooks
Quote mutations fire the following events (subscribe via webhook endpoints):
quote.createdquote.updatedquote.sentquote.acceptedquote.declinedquote.cancelledquote.deletedquote.restored