OQL Β· Entities

Deals

OQL field reference for deals. Sales opportunities linked to contacts, tracked through pipeline stages.

Last updated Jul 16, 2026

Deals are sales opportunities linked to contacts and tracked through pipeline stages. The financial fields are aggregatable, which makes deals the natural entity for revenue reporting.

Fields

Legend: F filterable, S sortable, A aggregatable, G groupable.

FieldTypeFSAGDescription
idIDYβ€”β€”β€”Deal ID
namestringYYβ€”β€”Deal name
textstringβ€”β€”β€”β€”Deal description / notes (free text; writable via create/update)
contact_idIDYβ€”β€”YAssociated contact ID
owner_idIDYβ€”β€”YDeal owner user ID
statusstringYYβ€”YOne of pending, won, lost
amountnumberYYYβ€”Deal value
total_amountnumberYYYβ€”Total amount including recurring months
costnumberYYYβ€”Deal cost (if cost tracking is enabled)
total_costnumberYYYβ€”Total cost including recurring months
marginnumberYYYβ€”Profit margin (amount - cost)
commissionnumberYYYβ€”Commission amount
commission_percentagenumberYβ€”Yβ€”Commission percentage
commission_typestringYβ€”β€”YHow commission is expressed: none, percentage, or absolute
commission_basestringYβ€”β€”YWhat percentage commission is calculated from: amount or margin
pipeline_idIDYβ€”β€”YPipeline ID
stagenumberYYβ€”YPipeline stage number. Live for pending deals only.
last_stagenumber (virtual)YYβ€”β€”Final stage for closed deals (won, lost, and every delivery-pipeline deal)
expected_close_datedateYYβ€”YExpected close date (when status is pending)
close_datedateYYβ€”YActual close date (when status is won or lost)
monthsnumberYβ€”β€”β€”Number of recurring months
reason_loststring (output only)β€”β€”β€”β€”Reason lost display name
reason_lost_idIDYβ€”β€”YReason lost ID
has_deal_itemsbooleanYβ€”β€”β€”Whether the deal has line items
archivedbooleanYβ€”β€”YWhether the deal is archived
created_attimeYYβ€”YRecord creation timestamp
modified_attimeYYβ€”YLast modification timestamp

Notes

  • stage vs last_stage map to the same underlying value but are scoped by deal status. Pending deals expose stage; closed deals (won, lost, and every deal in a delivery pipeline) expose last_stage. The non-applicable one is null in projections, and filtering by stage implicitly restricts the result set to pending deals.
  • Stage values are integers but not sequential. A typical pipeline uses values like 10, 20, 40. Stage numbers and their labels are account-configurable.
  • Sales vs delivery pipelines. A pipeline is either a sales pipeline (deals run pending β†’ won/lost) or a delivery pipeline (post-sales project tracking, where every deal is won and the stages track delivery progress). Deals in a delivery pipeline are always won, so their position lives in last_stage, not stage. Use context() to see each pipeline’s type.
  • Financial fields (amount, total_amount, cost, total_cost, margin, commission, commission_percentage) are all aggregatable and valid as the argument to sum, avg, min, max, median, and percentile.
  • close_date is writable via the MCP create/update tools, but only on won or lost deals (or together with status: "won"/"lost" in the same call). Pending deals have no close date; setting it on one is rejected with a hint to use expected_close_date instead.
  • Lookups: contact (via contact_id). Pull the contact’s fields inline as contact.<field> β€” for example contact.last_name, contact.company, or contact.country_code β€” in select, where, and order_by. See Concepts β€Ί Lookups.
  • Custom fields are queryable by name as custom_fields.<name> in select, where, and order_by; select custom_fields.* (or *) to return all of them. Filterability and sortability depend on the field’s type. Numeric custom fields can also be aggregated ({ "sum": ["custom_fields.<name>"] }), and min/max work on date custom fields. group_by and distinct on custom fields are not supported: group by a top-level field and filter on the custom field in where instead. Use describe to discover an account’s custom-field names and types.

Example queries

Top 25 open deals by amount, each with its contact’s company (a lookup):

{
  "from": "deals",
  "select": ["name", "amount", "contact.company"],
  "where": { "status": "pending" },
  "order_by": [{ "amount": "desc" }],
  "limit": 25
}

Deals I own that closed last quarter:

{
  "from": "deals",
  "where": {
    "owner_id": "ME()",
    "status": "won",
    "close_date": "LAST_QUARTER()"
  }
}

Won revenue this quarter, by owner:

{
  "from": "deals",
  "select": ["owner_id", "count()", { "sum": ["amount"] }],
  "where": { "status": "won", "close_date": "THIS_QUARTER()" },
  "group_by": ["owner_id"]
}

Monthly closed-won trend over the last year:

{
  "from": "deals",
  "select": ["close_date", "count()", { "sum": ["amount"] }],
  "where": {
    "status": "won",
    "close_date": { ">=": { "DAYS_AGO": [365] } }
  },
  "group_by": [{ "MONTH": ["close_date"] }]
}

Stuck deals (in pipeline more than 90 days):

{
  "from": "deals",
  "where": {
    "status": "pending",
    "created_at": { "<": { "DAYS_AGO": [90] } }
  },
  "order_by": [{ "amount": "desc" }]
}