Skip to content

Get Comparables Trail

GET
/api/canvas/{deal_id}/comparables-trail
curl --request GET \
--url https://example.com/api/canvas/example/comparables-trail \
--header 'Authorization: Bearer <token>'

Return the typed-constraint trail + ranked comps for deal_id.

Response shape::

{
    "deal_id": "...",
    "available": True | False,
    "subject": {entity_id, address, asset_class, size_sf, ...} | None,
    "comps": [{rank, entity_id, name, ...}, ...],
    "constraint_trail": {
        "compatibility_group": "office" | None,
        "asset_classes_allowed": ["office_class_a", ...],
        "size_band": [lo, hi] | None,
        "vintage_band": [lo, hi] | None,
        "submarket": "..." | None,
    },
    "total_candidates": N,
    "returned_count": N,
}

Returns 200 with available: false when the property graph has not been populated for the deal (e.g. parse-time hook skipped, or extraction surfaced no subject Asset). The UI renders the empty state in that case.

deal_id
required
Deal Id
string

Successful Response

Media type application/json
ComparablesTrailResponse

Top-level response for GET /canvas/{deal_id}/comparables-trail.

object
deal_id
required
Deal Id
string
available
required
Available
boolean
subject
Any of:
SubjectAsset

Subject Asset metadata — the deal’s underwritten property.

object
entity_id
required
Entity Id
string
address
required
Address
string
asset_class
Any of:
string
size_sf
Any of:
number
year_built
Any of:
integer
submarket
Any of:
string
market
Any of:
string
property_class
Any of:
string
comps
required
Comps
Array<object>
ComparableRow

A single Comparable row in the typed-constraint result set.

object
rank
required
Rank
integer
entity_id
required
Entity Id
string
name
required
Name
string
address
Any of:
string
asset_class
Any of:
string
size_sf
Any of:
number
year_built
Any of:
integer
submarket
Any of:
string
market
Any of:
string
property_class
Any of:
string
sale_price
Any of:
number
rent_psf
Any of:
number
cap_rate
Any of:
number
comp_kind
required
Comp Kind
string
constraint_trail
required
ConstraintTrailModel

JSON-serialized view of the typed ConstraintTrail dataclass.

Distinct from the ConstraintTrail dataclass at src/intel/deal_graph/traversal.py — that one is the in-memory typed constraint record; this is the wire-format Pydantic model the Canvas API emits. Both must move in lockstep when a constraint field is added.

object
compatibility_group
Any of:
string
asset_classes_allowed
required
Asset Classes Allowed
Array<string>
size_band
Any of:
array
>= 2 items <= 2 items
vintage_band
Any of:
array
>= 2 items <= 2 items
submarket
Any of:
string
total_candidates
required
Total Candidates
integer
returned_count
required
Returned Count
integer
Example generated
{
"deal_id": "example",
"available": true,
"subject": {
"entity_id": "example",
"address": "example",
"asset_class": "example",
"size_sf": 1,
"year_built": 1,
"submarket": "example",
"market": "example",
"property_class": "example"
},
"comps": [
{
"rank": 1,
"entity_id": "example",
"name": "example",
"address": "example",
"asset_class": "example",
"size_sf": 1,
"year_built": 1,
"submarket": "example",
"market": "example",
"property_class": "example",
"sale_price": 1,
"rent_psf": 1,
"cap_rate": 1,
"comp_kind": "example"
}
],
"constraint_trail": {
"compatibility_group": "example",
"asset_classes_allowed": [
"example"
],
"size_band": [
"example"
],
"vintage_band": [
"example"
],
"submarket": "example"
},
"total_candidates": 1,
"returned_count": 1
}

Validation Error

Media type application/json
HTTPValidationError
object
detail
Detail
Array<object>
ValidationError
object
loc
required
Location
Array
msg
required
Message
string
type
required
Error Type
string
input
Input
ctx
Context
object
Example generated
{
"detail": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example",
"input": "example",
"ctx": {}
}
]
}