Skip to main content

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

GET/api/workspace/v1/quotes
GET/api/workspace/v1/quotes/{id}
POST/api/workspace/v1/quotes
PATCH/api/workspace/v1/quotes/{id} (draft only)
POST/api/workspace/v1/quotes/{id}/send
POST/api/workspace/v1/quotes/{id}/cancel
DELETE/api/workspace/v1/quotes/{id}
POST/api/workspace/v1/quotes/{id}/restore
POST/api/workspace/v1/quotes/bulk-delete

The quote object

FieldTypeDescription
crm_contact_id*integerContact the quote is addressed to (required on create)
crm_deal_idintegerOptional linked CRM deal
lines*array1-100 line items — see line schema below
notesstringFree-form notes shown on the quote PDF (<= 5000 chars)
valid_until_daysintegerValidity window in days (1-365, default 30)
discount_amountnumberAbsolute discount amount (before VAT)
discount_reasonstringShort reason surfaced on the quote
manual_labelstringOptional label (e.g. project reference)
referencestringFree-form PO / reference number
currencystring(3)ISO 4217 (defaults to workspace currency)
statusenumdraft | sent | accepted | declined | expired | converted | cancelled | superseded (read-only)

The line item

FieldTypeDescription
description*string1-500 chars
quantity*numberPositive quantity
unit_price*numberNon-negative unit price
vat_ratenumberVAT percentage 0-100 (default 21)
sort_orderintegerDisplay 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.created
  • quote.updated
  • quote.sent
  • quote.accepted
  • quote.declined
  • quote.cancelled
  • quote.deleted
  • quote.restored
Quotes - Workspace API - Staffify