Deals API
List, create, retrieve, update, and delete CRM deals.
List deals
GET /api/v1/crm/deals| Parameter | Type | Notes |
|---|---|---|
page | integer | Default 1 |
limit | integer | Default 50, maximum 100 |
status | string, repeatable | open, on_hold, closed_won, closed_lost |
stage | string, repeatable | discovery, qualified, proposal, negotiation, closed_won, closed_lost |
assignee | UUID, repeatable | Assigned user |
contact_id | UUID | Associated contact |
company_id | UUID | Associated company |
value_min | number | Minimum value |
value_max | number | Maximum value |
The response contains data and pagination.
Create a deal
POST /api/v1/crm/deals
Content-Type: application/jsonRequires deals.write.
{
"title": "Enterprise license",
"value": 50000,
"currency": "EUR",
"stage": "qualified",
"status": "open",
"contact_id": "00000000-0000-0000-0000-000000000000",
"expected_close_date": "2026-08-31",
"probability": 75
}title is required. Enum values are lowercase.
Optional fields include description, contact_id, company_id,
assigned_to, status, stage, value, currency, probability,
expected_close_date, actual_close_date, lost_reason, source, tags,
custom_fields, external_id, price_book_id, package_id, rep_id,
developer_id, commission_pct, and territory.
The body is strict and rejects unknown fields.
Retrieve a deal
GET /api/v1/crm/deals/{id}Returns 404 when the deal is not present in the authenticated workspace.
Update a deal
PATCH /api/v1/crm/deals/{id}
Content-Type: application/jsonRequires deals.write. The body accepts the same optional fields as create and
must contain at least one field.
Delete a deal
DELETE /api/v1/crm/deals/{id}Requires deals.write. The service performs the CRM deal deletion behavior and
returns:
{
"data": {
"id": "deal-uuid",
"deleted": true
}
}
