The Deal object
The following fields are accepted on write via POST /api/v1/deals.
| Field | Type | Notes |
|---|---|---|
id | string | CUID, assigned on create (read-only) |
name | string (required) | Max 200 characters |
value | number | Nonnegative; defaults to 0 if omitted on create |
stage | enum | NEW (default) · QUALIFIED · PROPOSAL · NEGOTIATION · WON · LOST |
expectedCloseDate | string (ISO 8601 date) | null | When the deal is expected to close |
notes | string | null | Max 10,000 characters |
externalId | string | null | Your system's ID — upsert key and dedupe handle (max 200 chars) |
contactId | string | null | Link to an existing contact by its agentlyleads record ID |
companyId | string | null | Link to an existing company by its agentlyleads record ID |
offeringId | string | null | Link to an existing offering/product by its agentlyleads record ID |
contactExternalId | string | null | Resolve the linked contact by its externalId instead of contactId (max 200 chars) |
companyExternalId | string | null | Resolve the linked company by its externalId instead of companyId (max 200 chars) |
offeringExternalId | string | null | Resolve the linked offering by its externalId instead of offeringId (max 200 chars) |
createdAt | string (ISO 8601) | Assigned on create (read-only) |
updatedAt | string (ISO 8601) | Updated on every write (read-only) |
Example object
{
"id": "cmq1abc2def3ghi4jkl5",
"name": "Acme Corp — Annual Contract",
"value": 12000,
"stage": "QUALIFIED",
"expectedCloseDate": "2026-09-30",
"notes": null,
"externalId": "hs_deal_789",
"contactId": null,
"companyId": null,
"offeringId": null,
"createdAt": "2025-06-01T12:00:00.000Z",
"updatedAt": "2025-06-01T12:00:00.000Z"
}Notes on specific fields
name is the only required field. All other fields are optional on write.
value defaults to 0 when omitted on create. On update, only fields explicitly included in the request body are changed.
externalId is the upsert key. A row with an externalId that matches an existing deal in the workspace updates that deal instead of creating a duplicate.
Linking a contact, company, or offering can be done either by agentlyleads record ID (contactId/companyId/offeringId) or by an external system's ID (contactExternalId/companyExternalId/offeringExternalId), which is resolved against that record's own externalId. If an *ExternalId is supplied but no matching record exists in the workspace, that row fails — it does not fall back to leaving the deal unlinked.