Deals
A deal is an opportunity your team is working, such as a sale, a renewal, or an engagement, with one counterparty: a contact or an organization. Every deal sits in a stage of a pipeline. Moving it to a won or lost stage closes it; moving it back to an open stage reopens it. Use this resource to track deals and report on them.
A deal is visible to your key exactly when its pipeline is, and anyone who can see a deal can edit or delete it. Carom records every stage move, whether a person made it or an agent did.
Carom’s deal agent, auto_deal, reads incoming email and proposes new deals and stage moves as proposals. It works the pipelines whose dealmaker_enabled is true, and runs only while its agent configuration is enabled.
#The deal object
Returned by every deal endpoint. Retrieving a single deal adds activity previews and the stage history; updating one returns the stage history too.
Attributes
-
idstring · uuidUnique identifier for the deal.
-
namestring -
descriptionstring · nullable -
statusstringThe outcome of the deal’s current stage. You change it by moving the deal to another stage, not directly.
openwonlost -
amountnumber · nullableWhat the deal is worth, in
currency. Zero or more, and less than 10,000,000,000,000. -
currencystringISO 4217 code for
amount, such asUSD, the default. -
expected_close_datestring · date · nullableThe day your team expects the deal to close.
-
closed_atstring · date-time · nullableWhen the deal entered a won or lost stage. Null while the deal is open.
-
lost_reasonstring · nullableWhy the deal was lost. Cleared when the deal moves to an open or won stage.
-
pipeline_idstring · uuidThe pipeline the deal belongs to. Set when the deal is created and never changes.
-
pipeline_stage_idstring · uuidThe stage the deal is in, one of the pipeline’s
stages. -
contact_idstring · uuid · nullableThe counterparty, when it is a person. Exactly one of
contact_idandorganization_idis set. -
organization_idstring · uuid · nullableThe counterparty, when it is an organization.
-
contactobject · nullableA summary of the counterparty contact. Null when the counterparty is an organization or when the contact isn’t visible to your key.
Show 7 child attributesHide child attributes
idstring · uuidnamestring · nullablecontact_typestringAs on the contact object.
globalboolean · nullableTrue for a global contact, visible to the whole account; false for a personal one.
user_idstring · uuid · nullableThe user who owns the contact.
backgroundstring · nullableFree-form notes about the person.
avatarobject · nullableThe contact’s picture, as on the contact object.
-
organizationobject · nullableA summary of the counterparty organization. Null when the counterparty is a contact.
Show 5 child attributesHide child attributes
idstring · uuidnamestring · nullabledescriptionstring · nullabledomainstring · nullablelogoobject · nullable
-
owner_user_idstring · uuid · nullableThe user responsible for the deal. Null when the deal has no owner.
-
created_by_user_idstring · uuid · nullable -
pinnedboolean · nullableWhether your key’s user has pinned this deal.
-
created_atstring · date-time -
updated_atstring · date-time -
tagsarray of tags · nullableTags applied to this deal.
-
transitionsarray of objectsThe deal’s stage history, oldest first. The first entry records the stage the deal was created in. Present only on Retrieve and Update responses.
Show 8 child attributesHide child attributes
idstring · uuidfrom_stageobject · nullableThe stage the deal left, with its
id,name, andposition. Null on the first entry.positionis null for a stage that has since been removed.to_stageobjectThe stage the deal entered, with the same fields.
-
directionstring · nullableWhether the move went later or earlier in the pipeline, judged by the stages’ current positions. Null on the first entry and when either stage has since been removed.
forwardbackward occurred_atstring · date-timechanged_by_user_idstring · uuid · nullableThe user who made the move, or on whose behalf the proposal that made it was applied.
proposal_idstring · uuid · nullableThe proposal that made the move. Null for moves a person made directly. The id stays set after the proposal is deleted.
-
agentstring · nullableThe agent that wrote that proposal, such as the deal agent. Null for moves a person made directly.
assistantauto_dealauto_task
-
counts,tasks,eventsActivity previews, present only on Retrieve a deal.
{
"id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"description": "Three-year renewal covering all 14 Wildgrove properties.",
"status": "open",
"amount": 48000.0,
"currency": "USD",
"expected_close_date": "2026-10-15",
"closed_at": null,
"lost_reason": null,
"pipeline_id": "5e8a1c3f-7b2d-4f6e-a9c0-3d1b7e4f2a86",
"pipeline_stage_id": "c3e6a9b4-5d8f-4cab-9e3b-7f4dab2c6e93",
"contact_id": null,
"organization_id": "6b0e2d9a-4c31-4f8e-a7d2-90c4e1b7f5a3",
"contact": null,
"organization": {
"id": "6b0e2d9a-4c31-4f8e-a7d2-90c4e1b7f5a3",
"name": "Wildgrove Property Management",
"description": "Manages residential and mixed-use buildings in the East Bay.",
"domain": "wildgrove.example",
"logo": null
},
"owner_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"created_by_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"pinned": false,
"created_at": "2026-09-02T17:20:05.006Z",
"updated_at": "2026-09-16T15:02:44.646Z",
"tags": [
{
"id": "0f1e2d3c-4b5a-4968-8776-655443322110",
"name": "Customer",
"color": "#66b185",
…
}
]
}
#List deals
Returns the deals visible to your key, 50 per page by default, newest first. Filter by pipeline, stage, status, counterparty, owner, dates, or tags. All filters combine with AND.
This list uses page-number pagination.
Query parameters
-
slicestringA preset view.
mine: deals your key’s user owns.open: open deals.closing-soon: open deals with an expected close date no more than 30 days away, including overdue ones, sorted byexpected_close_date, earliest first.closed: won and lost deals, most recently closed first.mineopenclosing-soonclosed -
querystringMatch against deal names and descriptions. At most 500 characters.
-
pipeline_idstringComma-separated pipeline ids.
-
pipeline_stage_idstringComma-separated stage ids.
-
statusstringComma-separated statuses, such as
won,lost.openwonlost -
contact_idstring · uuidDeals whose counterparty is this contact.
-
organization_idstring · uuidDeals whose counterparty is this organization.
-
contact_ids,organization_idsstringComma-separated ids. A deal matches if its counterparty is any of the listed contacts or any of the listed organizations.
-
owner_user_idstringComma-separated user ids.
-
expected_close_beforestring · dateDeals expected to close on or before this day.
-
closed_afterstring · dateDeals closed on or after this day.
-
started_after,started_beforestring · dateDeals created on or after, or on or before, this day, as
YYYY-MM-DD. -
tagsstringComma-separated tag ids, at most 50. A deal matches if it carries any of them.
-
pageintegerdefault1 -
per_pageintegerdefault50At most 100; larger values are reduced to 100.
Returns
-
collectionobjectA page of deals and where it sits in the full list.
Show 8 child attributesHide child attributes
-
recordsarray of dealsUp to
per_pagedeals, withouttransitions. -
pageinteger -
per_pageinteger -
total_resultsinteger · nullableDeals matching the filters, across all pages.
-
pagesinteger · nullable -
sortstringThe field the list is sorted by:
created_at, orexpected_close_dateandclosed_atfor theclosing-soonandclosedslices. -
orderstring -
slice_keystring · nullableThe
sliceyou sent, echoed back. Null when you sent none.
-
Errors
- 400
invalid_requestA parameter is malformed, for example an id that isn’t a UUID, an unknownsliceorstatus, a date not in ISO 8601 form, or aquerylonger than 500 characters.
curl "https://api.carom.io/deals?slice=closing-soon&pipeline_id=5e8a1c3f-7b2d-4f6e-a9c0-3d1b7e4f2a86" \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"collection": {
"records": [
{
"id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"status": "open",
"amount": 48000.0,
"expected_close_date": "2026-10-15",
…
},
{
"id": "3c9e1a7f-5b2d-4c8e-a6f0-2d4b8e1c7a53",
"name": "Halvorsen Freight dispatch pilot",
"status": "open",
"amount": 12500.0,
"expected_close_date": "2026-10-09",
…
}
],
"slice_key": "closing-soon",
"sort": "expected_close_date",
"order": "asc",
"per_page": 50,
"page": 1,
"total_results": 2,
"pages": 1
}
}
#Create a deal
Creates a deal in a pipeline your key can see. Give exactly one counterparty, a contact_id or an organization_id. Without a pipeline_stage_id, the deal starts in the pipeline’s first stage.
The deal’s status comes from the stage’s outcome, so a deal created in a won or lost stage is closed immediately.
Request body application/json
-
dealobjectrequiredShow 10 child attributesHide child attributes
-
namestringrequired -
pipeline_idstring · uuidrequired -
pipeline_stage_idstring · uuidAn active stage of that pipeline. Defaults to its first stage.
-
contact_idstring · uuidRequired unless you give
organization_id. Not both. -
organization_idstring · uuidRequired unless you give
contact_id. Not both. -
descriptionstring -
amountnumberZero or more, and less than 10,000,000,000,000.
-
currencystringdefaultUSDThe ISO 4217 code of a currency in circulation, in uppercase, such as
EUR. Null or omitted meansUSD. -
expected_close_datestring · date -
owner_user_idstring · uuidA user in your account. Without it, the deal has no owner.
-
Returns
The new deal object, wrapped in deal, with status 201.
Errors
- 400
invalid_requestA field failed validation, for example a missingname, acurrencythat isn’t an ISO 4217 code, or both or neither ofcontact_idandorganization_id.error.fieldssays which. - 404
record_not_foundThe pipeline isn’t visible to your key, the stage isn’t an active stage of it, the contact isn’t visible to your key, or the organization or owner doesn’t exist in your account.
curl https://api.carom.io/deals \
-H "Authorization: Bearer $CAROM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deal": {
"name": "Wildgrove portfolio renewal",
"pipeline_id": "5e8a1c3f-7b2d-4f6e-a9c0-3d1b7e4f2a86",
"organization_id": "6b0e2d9a-4c31-4f8e-a7d2-90c4e1b7f5a3",
"amount": 48000,
"expected_close_date": "2026-10-15",
"owner_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e"
}
}'
{
"deal": {
"id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"status": "open",
"amount": 48000.0,
"currency": "USD",
"expected_close_date": "2026-10-15",
"pipeline_id": "5e8a1c3f-7b2d-4f6e-a9c0-3d1b7e4f2a86",
"pipeline_stage_id": "a1c4e7f2-3b6d-4a8e-9c1f-5d2b8e0a4c71",
"organization_id": "6b0e2d9a-4c31-4f8e-a7d2-90c4e1b7f5a3",
"owner_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"created_at": "2026-09-02T17:20:05.006Z",
…
}
}
#Retrieve a deal
Returns a single deal with its stage history, up to five open tasks, and up to three upcoming events with the counterparty.
Path parameters
-
idstring · uuidrequiredThe deal’s id.
Returns
The deal object, wrapped in deal, with transitions and these additional attributes.
-
countsobjectFull-set totals behind the
tasksandeventspreviews.Show 2 child attributesHide child attributes
open_tasksintegerOpen tasks attached to the deal and visible to your key.
upcoming_eventsintegerEvents with the counterparty that start today or later in your key’s user’s time zone.
-
tasksarray of tasksUp to five open tasks attached to the deal.
-
eventsarray of calendar eventsUp to three upcoming events with the counterparty, soonest first.
Errors
- 404
record_not_foundNo deal with that id is visible to your key.
curl https://api.carom.io/deals/8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17 \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"deal": {
"id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"status": "open",
"pipeline_stage_id": "c3e6a9b4-5d8f-4cab-9e3b-7f4dab2c6e93",
…
"counts": {
"open_tasks": 1,
"upcoming_events": 1
},
"tasks": [
{
"id": "e7f8a9b0-c1d2-4e3f-8a4b-5c6d7e8f9a01",
"assignment": "Send the Q4 renewal proposal",
"due": "2026-09-24",
…
}
],
"events": [
{
"id": "b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d12",
"name": "Wildgrove renewal review",
…
}
],
"transitions": [
{
"id": "f1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
"changed_by_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"proposal_id": null,
"agent": null,
"direction": null,
"occurred_at": "2026-09-02T17:20:05.006Z",
"from_stage": null,
"to_stage": {
"id": "a1c4e7f2-3b6d-4a8e-9c1f-5d2b8e0a4c71",
"name": "Lead",
"position": 0
}
},
{
"id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
"changed_by_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"proposal_id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
"agent": "auto_deal",
"direction": "forward",
"occurred_at": "2026-09-16T15:02:44.646Z",
"from_stage": {
"id": "a1c4e7f2-3b6d-4a8e-9c1f-5d2b8e0a4c71",
"name": "Lead",
"position": 0
},
"to_stage": {
"id": "c3e6a9b4-5d8f-4cab-9e3b-7f4dab2c6e93",
"name": "Proposal",
"position": 2
}
}
]
}
}
#Update a deal
Changes the fields you send and leaves the rest alone. Send null to clear a nullable field; currency can’t be null. A deal always keeps exactly one counterparty, so to switch from an organization to a contact, send the new contact_id together with "organization_id": null.
To move the deal, send a pipeline_stage_id from the same pipeline. A deal can’t change pipelines, and a pipeline_id in the body is ignored. Carom sets status from the new stage’s outcome and records the move in transitions. Moving into a won or lost stage sets closed_at; moving back to an open stage clears it. Moving to an open or won stage clears lost_reason.
Path parameters
-
idstring · uuidrequired
Request body application/json
-
dealobjectrequiredAny of the attributes accepted by Create a deal except
pipeline_id, pluslost_reason.Show 1 child attributeHide child attributes
-
lost_reasonstringWhy the deal was lost. Send it with a move to a lost stage, or while the deal is in one. A later move to an open or won stage clears it.
-
Returns
The updated deal object, wrapped in deal, with transitions.
Errors
- 400
invalid_requestA field failed validation, for example a null or unknowncurrency, or the change would leave the deal with both or neither counterparty.error.fieldssays which. - 404
record_not_foundNo deal with that id is visible to your key, the stage isn’t an active stage of the deal’s pipeline, a new contact isn’t visible to your key, or the organization or owner doesn’t exist in your account.
curl -X PATCH https://api.carom.io/deals/8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17 \
-H "Authorization: Bearer $CAROM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"deal": {
"pipeline_stage_id": "d4f7bac5-6e9a-4dbc-8f4c-8a5ebc3d7fa4",
"amount": 51500
}
}'
{
"deal": {
"id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"status": "won",
"amount": 51500.0,
"pipeline_stage_id": "d4f7bac5-6e9a-4dbc-8f4c-8a5ebc3d7fa4",
"closed_at": "2026-09-18T20:41:37.911Z",
…
"transitions": [
…
{
"id": "6c7d8e9f-0a1b-4c2d-8e3f-4a5b6c7d8e9f",
"changed_by_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"proposal_id": null,
"agent": null,
"direction": "forward",
"occurred_at": "2026-09-18T20:41:37.911Z",
"from_stage": {
"id": "c3e6a9b4-5d8f-4cab-9e3b-7f4dab2c6e93",
"name": "Proposal",
"position": 2
},
"to_stage": {
"id": "d4f7bac5-6e9a-4dbc-8f4c-8a5ebc3d7fa4",
"name": "Won",
"position": 3
}
}
]
}
}
#Delete a deal
Permanently deletes a deal. Anyone who can see the deal can delete it.
The deal’s stage history, the comments on it, and its pins are deleted with it, and its tags are removed. Tasks attached to the deal are kept and no longer point to it, including tasks your key can’t see. Pending proposals about the deal expire.
Path parameters
-
idstring · uuidrequired
Returns
An empty response with status 204.
Errors
- 404
record_not_foundNo deal with that id is visible to your key.
curl -X DELETE https://api.carom.io/deals/8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17 \
-H "Authorization: Bearer $CAROM_API_KEY"
No content
#Summarize deals
Totals the deals that List deals would return for the same filters: how many are open and what they’re worth, and how many were won in the last 30 days and what those were worth.
A deal counts as won in the window when its closed_at falls within it. Filters that exclude open or won deals, such as slice=closed or slice=open, make those counts and values 0.
Values add up amount as stored, without converting currencies, and count only deals in pipelines that track amounts. Deal counts include every matching deal.
Query parameters
-
slice,query,pipeline_id,pipeline_stage_id,contact_id,organization_id,contact_ids,organization_ids,owner_user_id,expected_close_before,closed_after,started_after,started_before,tagsAs on List deals. There is no
statusfilter, because the summary reports open and won deals side by side.
Returns
-
summaryobjectShow 5 child attributesHide child attributes
open_countintegerOpen deals.
open_valuenumberTotal
amountof open deals.won_countintegerDeals won within the last
won_window_days.won_valuenumberTotal
amountof those won deals.won_window_daysintegerCurrently 30.
Errors
- 400
invalid_requestA parameter is malformed, as on List deals.
curl "https://api.carom.io/deals/summary?pipeline_id=5e8a1c3f-7b2d-4f6e-a9c0-3d1b7e4f2a86" \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"summary": {
"open_count": 12,
"open_value": 214500.0,
"won_count": 3,
"won_value": 61000.0,
"won_window_days": 30
}
}
#Retrieve the deal report
Returns one flat row per deal across every pipeline visible to your key, for building your own reports. The report holds every open deal and every deal won or lost in the last 24 months, up to 5,000 deals. It takes no parameters; filter and aggregate the rows yourself.
Open deals are always included. If the total would exceed 5,000, Carom leaves out the oldest closed deals first and says so with truncated, omitted_count, and window_start. For a single pipeline with stage history, use Retrieve a pipeline report.
Returns
-
reportobjectShow 4 child attributesHide child attributes
truncatedbooleanTrue when closed deals were left out to stay within 5,000.
omitted_countintegerHow many closed deals were left out.
window_startstring · dateThe report includes every deal closed on or after this day: 24 months ago, or later when closed deals were left out.
-
dealsarray of objectsOpen deals newest first, then closed deals most recently closed first.
Show 13 child attributesHide child attributes
idstring · uuidnamestringstatusstringopenwonlostpipeline_idstring · uuidpipeline_stage_idstring · uuidamountnumber · nullableexpected_valuenumber · nullableFor an open deal,
amounttimes its stage’slikelihood; the full amount for a won deal; 0 for a lost one. Null when the deal has no amount or its pipeline doesn’t track amounts.owner_user_idstring · uuid · nullablecreated_atstring · date-timeclosed_atstring · date-time · nullableexpected_close_datestring · date · nullablecurrent_stage_entered_atstring · date-time · nullableWhen an open deal last entered its current stage. Null for closed deals.
lost_reasonstring · nullable
curl https://api.carom.io/deals/report \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"report": {
"truncated": false,
"omitted_count": 0,
"window_start": "2024-09-19",
"deals": [
{
"id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"status": "open",
"pipeline_id": "5e8a1c3f-7b2d-4f6e-a9c0-3d1b7e4f2a86",
"pipeline_stage_id": "c3e6a9b4-5d8f-4cab-9e3b-7f4dab2c6e93",
"amount": 48000.0,
"expected_value": 33600.0,
"owner_user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"created_at": "2026-09-02T17:20:05.006Z",
"closed_at": null,
"expected_close_date": "2026-10-15",
"current_stage_entered_at": "2026-09-16T15:02:44.646Z",
"lost_reason": null
},
…
]
}
}
#Retrieve a deal’s discussion
Returns the comments your team has left on this deal and on its counterparty, grouped into scopes. Comments are internal; the counterparty never sees them.
The first scope is the deal itself and is always present. When the counterparty is an organization, the next scopes are the organization and the people who work there; when it’s a contact, the next scope is that contact. Those scopes appear only when they hold at least one comment visible to your key. Every visible comment is included; the discussion isn’t paginated.
Path parameters
-
idstring · uuidrequired
Returns
-
discussionobjectShow 1 child attributeHide child attributes
-
scopesarray of objectsOne entry per group of records: the deal first, then the others.
Show 6 child attributesHide child attributes
keystringdealorganizationpeoplecontactlabelstringA heading for the scope:
This deal, the counterparty’s name, orPeople atfollowed by the organization’s name. Display text; usekeyto identify a scope.unitstringA plural noun for the scope’s records, for display:
deals,organizations, orpeople.primarybooleanTrue for the deal’s own scope.
total_commentsinteger-
recordsarray of objectsThe commented records in the scope, most recently discussed first.
Show 6 child attributesHide child attributes
keystringThe record type and id, joined by a hyphen.
record_typestringdealorganizationcontactrecord_idstring · uuidnamestring · nullabletotal_commentsintegercommentsarray of commentsOldest first.
-
Errors
- 404
record_not_foundNo deal with that id is visible to your key.
curl https://api.carom.io/deals/8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17/discussion \
-H "Authorization: Bearer $CAROM_API_KEY"
{
"discussion": {
"scopes": [
{
"key": "deal",
"label": "This deal",
"unit": "deals",
"primary": true,
"total_comments": 1,
"records": [
{
"key": "deal-8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"record_type": "deal",
"record_id": "8f2b6d4a-1c9e-4a7b-b3d5-0e6f8a2c4d17",
"name": "Wildgrove portfolio renewal",
"total_comments": 1,
"comments": [
{
"id": "c4d5e6f7-a8b9-4c0d-9e1f-2a3b4c5d6e7f",
"html_content": "<p>Legal signed off on the three-year term. Sending paper Monday.</p>",
"text": null,
"user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
"created_at": "2026-09-17T16:05:31.821Z",
…
}
]
}
]
},
{
"key": "people",
"label": "People at Wildgrove Property Management",
"unit": "people",
"primary": false,
"total_comments": 1,
"records": [
…
]
}
]
}
}