Skip to content

Deals API

Deals API

Deals represent sales opportunities in your pipeline. Each deal has a stage, value, and can be associated with an organization, contact, and assigned to a team member.

Endpoints Overview

MethodEndpointDescription
GET/api-v1-dealsList all deals with filtering, sorting, and pagination
GET/api-v1-deals/:idGet a single deal with related data
POST/api-v1-dealsCreate a new deal
PATCH/api-v1-deals/:idUpdate an existing deal
PATCH/api-v1-deals/:id/stageUpdate deal stage only (optimized endpoint)
DELETE/api-v1-deals/:idSoft delete a deal

Required Scopes

  • Read operations: read:deals
  • Write operations: write:deals

List Deals

List all deals with support for filtering, sorting, pagination, and expanding related data.

Endpoint: GET /api-v1-deals

Scope: read:deals

Query Parameters

Pagination

ParameterTypeDefaultDescription
limitinteger50Number of records per page (max: 100)
pageinteger1Page number for offset-based pagination
per_pageinteger50Alternative to limit for offset-based pagination
cursorstring-Cursor for cursor-based pagination

Filtering

Filters can be applied using the following syntax:

  • Simple equality: ?stage_id=uuid
  • With operator: ?value[gte]=1000 or ?title[like]=Enterprise

Supported operators: eq, ne, gt, gte, lt, lte, like, in

Filterable fields:

  • title - Deal title (string)
  • stage_id - Deal stage UUID
  • organization_id - Associated organization UUID
  • contact_id - Associated contact UUID
  • assigned_to - Assigned user UUID
  • created_at - Creation timestamp (ISO 8601)
  • expected_close_date - Expected close date (ISO 8601)

Sorting

Use the sort parameter with field name. Prefix with - for descending order.

Examples:

  • ?sort=title - Sort by title ascending
  • ?sort=-value - Sort by value descending

Sortable fields: title, value, created_at, updated_at, expected_close_date

Use the include parameter to expand related resources in the response:

?include=organization,contact,stage,assigned_user

Available includes:

  • organization - Include organization details
  • contact - Include contact details
  • stage - Include deal stage details
  • assigned_user - Include assigned user details

Response

Returns a paginated list of deals.

Without includes:

{
"data": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Q1 Bulk Order",
"value": 25000,
"currency": "EUR",
"stage_id": "stage-uuid-1",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-03-31",
"probability": 75,
"metadata": {},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"pagination": {
"total": 150,
"limit": 50,
"page": 1,
"per_page": 50,
"total_pages": 3,
"has_more": true
}
}

With includes:

{
"data": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Q1 Bulk Order",
"value": 25000,
"currency": "EUR",
"stage_id": "stage-uuid-1",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-03-31",
"probability": 75,
"metadata": {},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"organization": {
"id": "org-uuid-1",
"name": "Acme Retail Shop",
"status": "active"
},
"contact": {
"id": "contact-uuid-1",
"first_name": "John",
"last_name": "Doe"
},
"stage": {
"id": "stage-uuid-1",
"name": "Qualified",
"color": "#3b82f6",
"position": 2
},
"assigned_user": {
"id": "user-uuid-1",
"full_name": "Sarah Smith",
"email": "sarah@company.com"
}
}
],
"pagination": {
"total": 150,
"limit": 50,
"page": 1,
"per_page": 50,
"total_pages": 3,
"has_more": true
}
}

Example Request

Terminal window
curl -X GET "https://your-project.supabase.co/functions/v1/api-v1-deals?limit=20&include=organization,stage&value[gte]=10000&sort=-value" \
-H "Authorization: Bearer YOUR_API_KEY"

Get Single Deal

Retrieve a single deal by its unique ID with all related data.

Endpoint: GET /api-v1-deals/:id

Scope: read:deals

Path Parameters

ParameterTypeRequiredDescription
idUUIDYesDeal ID

Response

Returns a single deal with all related data (organization, contact, stage, assigned user).

{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Q1 Bulk Order",
"value": 25000,
"currency": "EUR",
"stage_id": "stage-uuid-1",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-03-31",
"probability": 75,
"metadata": {},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"organization": {
"id": "org-uuid-1",
"name": "Acme Retail Shop",
"status": "active"
},
"contact": {
"id": "contact-uuid-1",
"first_name": "John",
"last_name": "Doe"
},
"stage": {
"id": "stage-uuid-1",
"name": "Qualified",
"color": "#3b82f6",
"position": 2
},
"assigned_user": {
"id": "user-uuid-1",
"full_name": "Sarah Smith",
"email": "sarah@company.com"
}
}
}

Example Request

Terminal window
curl -X GET "https://your-project.supabase.co/functions/v1/api-v1-deals/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer YOUR_API_KEY"

Error Responses

404 Not Found:

{
"error": {
"code": "NOT_FOUND",
"message": "Deal not found"
}
}

Create Deal

Create a new deal in your pipeline.

Endpoint: POST /api-v1-deals

Scope: write:deals

Request Body

FieldTypeRequiredDescription
titlestringYesDeal title (trimmed, non-empty)
valuenumberNoDeal value (default: 0)
currencystringNoCurrency code (default: “EUR”)
stage_idUUIDNoDeal stage (defaults to first stage if not provided)
organization_idUUIDNoAssociated organization (must exist in your company)
contact_idUUIDNoAssociated contact (must exist in your company)
assigned_toUUIDNoUser assigned to this deal
expected_close_datestringNoExpected close date (ISO 8601 format: YYYY-MM-DD)
probabilitynumberNoWin probability percentage (0-100)
metadataobjectNoCustom metadata as JSON object

Response

Returns the created deal with all related data and a 201 Created status.

{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Q1 Bulk Order",
"value": 25000,
"currency": "EUR",
"stage_id": "stage-uuid-1",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-03-31",
"probability": 75,
"metadata": {},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"organization": {
"id": "org-uuid-1",
"name": "Acme Retail Shop",
"status": "active"
},
"contact": {
"id": "contact-uuid-1",
"first_name": "John",
"last_name": "Doe"
},
"stage": {
"id": "stage-uuid-1",
"name": "Qualified",
"color": "#3b82f6",
"position": 2
},
"assigned_user": {
"id": "user-uuid-1",
"full_name": "Sarah Smith",
"email": "sarah@company.com"
}
}
}

Example Request

Terminal window
curl -X POST "https://your-project.supabase.co/functions/v1/api-v1-deals" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 Bulk Order",
"value": 25000,
"currency": "EUR",
"stage_id": "stage-uuid-1",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-03-31",
"probability": 75
}'

Error Responses

400 Validation Error (missing title):

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Title is required",
"details": [
{
"field": "title",
"message": "Title is required"
}
]
}
}

400 Validation Error (invalid stage):

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid stage",
"details": [
{
"field": "stage_id",
"message": "Stage not found or does not belong to your company"
}
]
}
}

400 Validation Error (invalid organization):

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Organization not found",
"details": [
{
"field": "organization_id",
"message": "Organization not found"
}
]
}
}

Update Deal

Update an existing deal. Only provided fields will be updated.

Endpoint: PATCH /api-v1-deals/:id

Scope: write:deals

Path Parameters

ParameterTypeRequiredDescription
idUUIDYesDeal ID

Request Body

All fields are optional. Only include fields you want to update.

FieldTypeDescription
titlestringDeal title
valuenumberDeal value
currencystringCurrency code
stage_idUUIDDeal stage (must belong to your company)
organization_idUUID or nullAssociated organization (set to null to remove)
contact_idUUID or nullAssociated contact (set to null to remove)
assigned_toUUID or nullAssigned user (set to null to unassign)
expected_close_datestring or nullExpected close date (ISO 8601 or null)
probabilitynumberWin probability percentage (0-100)
metadataobjectCustom metadata (replaces existing)

Response

Returns the updated deal with all related data.

{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Q1 Bulk Order - Updated",
"value": 30000,
"currency": "EUR",
"stage_id": "stage-uuid-2",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-04-15",
"probability": 85,
"metadata": {},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-16T14:20:00Z",
"organization": {
"id": "org-uuid-1",
"name": "Acme Retail Shop",
"status": "active"
},
"contact": {
"id": "contact-uuid-1",
"first_name": "John",
"last_name": "Doe"
},
"stage": {
"id": "stage-uuid-2",
"name": "Sample Sent",
"color": "#8b5cf6",
"position": 3
},
"assigned_user": {
"id": "user-uuid-1",
"full_name": "Sarah Smith",
"email": "sarah@company.com"
}
}
}

Example Request

Terminal window
curl -X PATCH "https://your-project.supabase.co/functions/v1/api-v1-deals/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 Bulk Order - Updated",
"value": 30000,
"stage_id": "stage-uuid-2",
"probability": 85
}'

Error Responses

404 Not Found:

{
"error": {
"code": "NOT_FOUND",
"message": "Deal not found"
}
}

400 No Fields:

{
"error": {
"code": "INVALID_REQUEST",
"message": "No fields to update"
}
}

Update Deal Stage

Optimized endpoint for updating only the deal stage. This is commonly used for drag-and-drop pipeline interfaces.

Endpoint: PATCH /api-v1-deals/:id/stage

Scope: write:deals

Path Parameters

ParameterTypeRequiredDescription
idUUIDYesDeal ID

Request Body

FieldTypeRequiredDescription
stage_idUUIDYesNew deal stage UUID (must belong to your company)

Response

Returns the updated deal with all related data.

{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Q1 Bulk Order",
"value": 25000,
"currency": "EUR",
"stage_id": "stage-uuid-3",
"organization_id": "org-uuid-1",
"contact_id": "contact-uuid-1",
"assigned_to": "user-uuid-1",
"expected_close_date": "2024-03-31",
"probability": 75,
"metadata": {},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-16T14:25:00Z",
"organization": {
"id": "org-uuid-1",
"name": "Acme Retail Shop",
"status": "active"
},
"contact": {
"id": "contact-uuid-1",
"first_name": "John",
"last_name": "Doe"
},
"stage": {
"id": "stage-uuid-3",
"name": "First Order",
"color": "#10b981",
"position": 4
},
"assigned_user": {
"id": "user-uuid-1",
"full_name": "Sarah Smith",
"email": "sarah@company.com"
}
}
}

Example Request

Terminal window
curl -X PATCH "https://your-project.supabase.co/functions/v1/api-v1-deals/123e4567-e89b-12d3-a456-426614174000/stage" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stage_id": "stage-uuid-3"
}'

Error Responses

400 Validation Error (missing stage_id):

{
"error": {
"code": "INVALID_REQUEST",
"message": "stage_id is required"
}
}

400 Validation Error (invalid stage):

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid stage",
"details": [
{
"field": "stage_id",
"message": "Stage not found"
}
]
}
}

Delete Deal

Soft delete a deal. The deal is not permanently deleted but marked with a deleted_at timestamp and will no longer appear in API responses.

Endpoint: DELETE /api-v1-deals/:id

Scope: write:deals

Path Parameters

ParameterTypeRequiredDescription
idUUIDYesDeal ID

Response

Returns a deletion confirmation.

{
"data": {
"deleted": true
}
}

Example Request

Terminal window
curl -X DELETE "https://your-project.supabase.co/functions/v1/api-v1-deals/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer YOUR_API_KEY"

Error Responses

404 Not Found:

{
"error": {
"code": "NOT_FOUND",
"message": "Deal not found"
}
}

Deal Stages

Deal stages represent the pipeline stages in your sales process. Each company has its own set of deal stages with custom names, colors, and positions.

Common default stages include:

  • Lead - Initial contact or inquiry
  • Qualified - Qualified opportunity
  • Sample Sent - Product sample sent
  • First Order - First order placed
  • Active Customer - Ongoing customer relationship
  • At Risk - Customer relationship at risk
  • Lost - Lost opportunity

Stages are ordered by the position field and can be customized per company.


Deal Fields Explained

value & currency

The monetary value of the deal. value is a number and currency is a 3-letter currency code (e.g., “EUR”, “USD”, “GBP”). Used for revenue forecasting and reporting.

probability

Win probability percentage (0-100). Represents the likelihood of closing this deal. Can be used for weighted pipeline forecasting.

expected_close_date

The expected date when the deal will close (ISO 8601 date format: YYYY-MM-DD). Used for pipeline forecasting and follow-up reminders.

metadata

Custom JSON object for storing additional data specific to your use case. The API does not validate the structure of this field.


Multi-Tenant Isolation

All deals are automatically scoped to your company. You can only access deals that belong to your company (determined by your API key’s company_id).

When creating or updating a deal:

  • stage_id must belong to your company
  • organization_id (if provided) must belong to your company
  • contact_id (if provided) must belong to your company

  • Organizations: Deals can be associated with an organization. See Organizations API
  • Contacts: Deals can be associated with a contact. See Contacts API
  • Deal Stages: Manage custom pipeline stages (documentation coming soon)