Deals
A deal is an opportunity on one of your pipelines. Moving a deal between stages is its own call, so stage rules and required fields are checked the way the board checks them.
Scopes: deals:read to read, deals:write to change.
The deal object
idstringThe deal’s id.
namestringDeal name.
pipeline_idstringWhich pipeline it is on. "default" unless you have several.
stagestringThe stage key, as your pipeline names it.
statusstringOpen, won, lost, or parked (off the board until a date). One of open, won, lost, parked.
amountnumber, nullableValue of the deal.
currencystringThree-letter currency code.
probabilityinteger, nullableChance of winning, 0 to 100, from the stage.
forecast_categorystringForecast category, from the stage. One of pipeline, best_case, commit, omitted.
expected_close_datetimestamp, nullableWhen you expect it to close.
next_stepobject, nullableWhat happens next, and when.
company_namestring, nullableThe account’s name.
company_domainstring, nullableThe account’s website domain.
company_idstring, nullableThe company record, if any.
primary_contact_idstring, nullableThe main contact on the deal.
contactsarray of objectEveryone on the deal, with their role.
closed_attimestamp, nullableWhen it was won or lost.
close_reason_codestring, nullableWhy it was won or lost: one of your reason keys.
owner_seat_idstring, nullableThe teammate who owns the deal. Null when nobody does.
sourcestring, nullableHow it was created, for example "manual" or "api:Warehouse sync".
custom_fieldsobjectYour own fields (Settings › Data model), by key. GET /custom-fields lists their keys, labels and types. A field with no value is left out.
created_attimestampWhen the deal was created.
updated_attimestampWhen the deal last changed.
{
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
}Endpoints
List deals
Deals on every pipeline, oldest first unless you sort. Deleted deals are left out. A key acting for one person sees only the deals that person can see.
statusstringopen, won, lost or parked.
stagestringA stage key.
pipeline_idstringA pipeline. Omit for every pipeline.
sortstringOrder by one field, oldest or smallest first; put - in front for newest or largest first. Empty values come first ascending and last descending. Default: oldest first. Keep the same sort while you follow next_cursor.
limitintegerHow many to return, 1 to 100. Default 25.
cursorstringThe next_cursor from the previous page.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl "https://api.useworkloom.com/api/public/v1/deals?limit=25" \
-H "Authorization: Bearer $WORKLOOM_KEY"const res = await fetch("https://api.useworkloom.com/api/public/v1/deals?limit=25", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
}
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.useworkloom.com/api/public/v1/deals?limit=25",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json(){
"data": [
{
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
}
],
"has_more": true,
"next_cursor": "66f5c3d1e4b0a1b2c3d4c3d4"
}Create a deal
Opens a deal with the same rules as the board: the stage must exist, a lost stage needs a reason, a stage’s required fields must be filled, and a contact has at most one open deal per pipeline.
Idempotency-KeystringAny unique string, up to 255 characters. Send the same key when you retry and the request runs once; the first answer comes back with Idempotent-Replayed: true. Kept 24 hours.
namestringDeal name. Defaults to the main contact’s company, then their name.
pipeline_idstringWhich pipeline. Defaults to "default".
stagestringStage key. Defaults to the pipeline’s first open stage.
amountnumber, nullableValue of the deal.
currencystringThree-letter currency code. Defaults to USD.
expected_close_datetimestamp, nullableWhen you expect it to close.
next_stepobject or string, nullableWhat happens next: { "text": "Send the proposal", "due_at": "2026-11-02T10:00:00Z" }, or just the text.
company_namestring, nullableThe account’s name.
company_domainstring, nullableThe account’s website domain.
company_idstring, nullableA company record to open it against.
primary_contact_idstring, nullableThe main contact. One open deal per contact per pipeline.
contactsarray of objectEveryone on the deal. Replaces the list.
owner_seat_idstring, nullableWho owns it. Only a key that acts for the whole workspace may set this.
reason_codestring, nullableNeeded when the stage is a lost stage: one of your lost reasons.
reason_notestring, nullableA note on why it closed.
fieldsobjectYour own fields, by key (Settings › Data model). Values are checked against each field’s type.
custom_fieldsobjectThe same as fields, by the name the deal object uses.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
409duplicate, conflict or idempotency_key_in_use.
422idempotency_key_reused or stage_requirements_missing.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl -X POST "https://api.useworkloom.com/api/public/v1/deals" \
-H "Authorization: Bearer $WORKLOOM_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Brightline, 10 seats",
"amount": 29900,
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"expected_close_date": "2026-11-14"
}'const res = await fetch("https://api.useworkloom.com/api/public/v1/deals", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID()
},
body: JSON.stringify({
"name": "Brightline, 10 seats",
"amount": 29900,
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"expected_close_date": "2026-11-14"
})
});
const data = await res.json();import os, uuid, requests
res = requests.post(
"https://api.useworkloom.com/api/public/v1/deals",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"name": "Brightline, 10 seats",
"amount": 29900,
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"expected_close_date": "2026-11-14"
},
)
data = res.json(){
"data": {
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
},
"livemode": true
}Get a deal
Returns one deal.
idstringRequiredThe deal’s id.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
404not_found.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl "https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4" \
-H "Authorization: Bearer $WORKLOOM_KEY"const res = await fetch("https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
}
});
const data = await res.json();import os, requests
res = requests.get(
"https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json(){
"data": {
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
}
}Update a deal
Changes only the fields you send. The stage changes through the move endpoint, and probability and forecast_category come from the stage.
idstringRequiredThe deal’s id.
namestringDeal name.
amountnumber, nullableValue of the deal. Null clears it.
currencystringThree-letter currency code.
expected_close_datetimestamp, nullableWhen you expect it to close. Null clears it.
next_stepobject or string, nullableWhat happens next: { "text": "Send the proposal", "due_at": "2026-11-02T10:00:00Z" }, or just the text.
company_namestring, nullableThe account’s name.
company_domainstring, nullableThe account’s website domain.
primary_contact_idstring, nullableThe main contact.
contactsarray of objectEveryone on the deal. Replaces the list.
owner_seat_idstring, nullableHand the deal to a teammate. Null leaves it unowned.
reasonstring, nullableWhy it changed owner. Needed when the key’s role does not reach every record.
fieldsobjectYour own fields, by key (Settings › Data model). Values are checked against each field’s type.
custom_fieldsobjectThe same as fields, by the name the deal object uses.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
404not_found.
409duplicate, conflict or idempotency_key_in_use.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl -X PATCH "https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4" \
-H "Authorization: Bearer $WORKLOOM_KEY" \
-H "Content-Type: application/json" \
-d '{
"expected_close_date": "2026-11-21",
"next_step": {
"text": "Send the security review",
"due_at": "2026-10-10T09:00:00Z"
}
}'const res = await fetch("https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"expected_close_date": "2026-11-21",
"next_step": {
"text": "Send the security review",
"due_at": "2026-10-10T09:00:00Z"
}
})
});
const data = await res.json();import os, requests
res = requests.patch(
"https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
json={
"expected_close_date": "2026-11-21",
"next_step": {
"text": "Send the security review",
"due_at": "2026-10-10T09:00:00Z"
}
},
)
data = res.json(){
"data": {
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
},
"livemode": true
}Delete a deal
Deletes the deal. Its contact can be given a new deal in the same pipeline straight away. A key acting for one person needs that person’s permission to delete records.
idstringRequiredThe deal’s id.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
404not_found.
409duplicate, conflict or idempotency_key_in_use.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl -X DELETE "https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4" \
-H "Authorization: Bearer $WORKLOOM_KEY"const res = await fetch("https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
}
});
const data = await res.json();import os, requests
res = requests.delete(
"https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json(){
"data": {
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"deleted": true
},
"livemode": true
}Move a deal
Moves a deal to another stage of its pipeline, won and lost included. A lost stage needs reason_code, one of your lost reasons. A stage’s required fields must be filled, on the deal or in fields, or the move is refused naming them.
idstringRequiredThe deal’s id.
Idempotency-KeystringAny unique string, up to 255 characters. Send the same key when you retry and the request runs once; the first answer comes back with Idempotent-Replayed: true. Kept 24 hours.
stagestringRequiredThe stage key to move to.
reason_codestring, nullableNeeded for a lost stage: one of your lost reasons. Optional for won.
reason_notestring, nullableA note on why.
competitorstring, nullableWho it was lost to, if anyone.
fieldsobjectValues the new stage asks for (its required fields), by key.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
404not_found.
409duplicate, conflict or idempotency_key_in_use.
422idempotency_key_reused or stage_requirements_missing.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl -X POST "https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4/move" \
-H "Authorization: Bearer $WORKLOOM_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"stage": "won"
}'const res = await fetch("https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4/move", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID()
},
body: JSON.stringify({
"stage": "won"
})
});
const data = await res.json();import os, uuid, requests
res = requests.post(
"https://api.useworkloom.com/api/public/v1/deals/66f5c3d1e4b0a1b2c3d4c3d4/move",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"stage": "won"
},
)
data = res.json(){
"data": {
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
},
"livemode": true
}Search deals
Deals matching every filter, oldest first unless you sort (created_at, updated_at, amount, expected_close_date or closed_at), paged like the list. Searchable: name, pipeline_id, stage, status, amount, currency, expected_close_date, closed_at, close_reason_code, company_name, company_domain, company_id, primary_contact_id, owner_seat_id, source, created_at, updated_at, and custom_fields.<key>.
filtersarray of SearchFilterUp to 20 filters. All must match.
limitintegerHow many to return, 1 to 100. Default 25.
cursorstring, nullableThe next_cursor from the previous page.
sortstring, nullableOrder by one field, as sort on the list: - in front for newest or largest first. Keep the same sort while you follow next_cursor.
400invalid_request, unknown_fields, reason_required or unsupported_version.
401authentication_required or invalid_key.
403missing_scope, forbidden, seat_inactive or organisation_inactive.
409duplicate, conflict or idempotency_key_in_use.
429rate_limited. Wait Retry-After seconds.
500internal_error.
curl -X POST "https://api.useworkloom.com/api/public/v1/deals/search" \
-H "Authorization: Bearer $WORKLOOM_KEY" \
-H "Content-Type: application/json" \
-d '{
"filters": [
{
"field": "stage",
"op": "in",
"value": [
"proposal",
"commit"
]
},
{
"field": "amount",
"op": "gte",
"value": 10000
}
]
}'const res = await fetch("https://api.useworkloom.com/api/public/v1/deals/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"filters": [
{
"field": "stage",
"op": "in",
"value": [
"proposal",
"commit"
]
},
{
"field": "amount",
"op": "gte",
"value": 10000
}
]
})
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.useworkloom.com/api/public/v1/deals/search",
headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
json={
"filters": [
{
"field": "stage",
"op": "in",
"value": [
"proposal",
"commit"
]
},
{
"field": "amount",
"op": "gte",
"value": 10000
}
]
},
)
data = res.json(){
"data": [
{
"id": "66f5c3d1e4b0a1b2c3d4c3d4",
"name": "Brightline, 10 seats",
"pipeline_id": "default",
"stage": "proposal",
"status": "open",
"amount": 29900,
"currency": "USD",
"probability": 50,
"forecast_category": "best_case",
"expected_close_date": "2026-11-14T00:00:00.000Z",
"next_step": {
"text": "Call with VP Finance",
"due_at": "2026-10-09T10:00:00.000Z"
},
"company_name": "Brightline",
"company_domain": "brightline.example",
"company_id": "66f19b77e4b0a1b2c3d4a1b2",
"primary_contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"contacts": [
{
"contact_id": "66f2a1c0e4b0a1b2c3d4e5f6",
"role": "champion"
}
],
"closed_at": null,
"close_reason_code": null,
"owner_seat_id": "66e0f1a2e4b0a1b2c3d40a0b",
"source": "api:Warehouse sync",
"custom_fields": {
"competitor": "Pipedrive"
},
"created_at": "2026-09-25T12:00:00.000Z",
"updated_at": "2026-10-03T08:42:10.000Z"
}
],
"has_more": true,
"next_cursor": "66f5c3d1e4b0a1b2c3d4c3d4"
}