Headless runs
One execution of a headless search: its progress, its shortlist, its pool. It is not a run of a search under Searches.
List a search's runs
/api/v1/search/{searchId}/executionsThe runs of one search, newest first, each at a glance. Read a run itself for its plays, its spend and its answer.
An API key carrying the scope named here, or a signed-in session.
- Scope
search:read- Key kinds
- PersonalOrganization
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
searchId | Path | string (uuid) | Required | The saved search's id. |
limit | Query | integer | Optional | How many to return: 1 to 50, 20 when absent. A number outside that range is clamped; text is ignored. |
cursor | Query | string | Optional | Where the last page ended: the cursor inside the previous page's links.next. Pass links as given; a cursor you edit is refused. |
Examples
curl "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
One page of runs.
{
"data": [
{
"id": "0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "succeeded",
"step": "compliance",
"stepLabel": "Checking fair housing",
"attempts": 1,
"progress": {
"done": 9,
"total": 9,
"percent": 100
},
"createdAt": "2026-10-02T14:03:12.118Z",
"startedAt": "2026-10-02T14:03:13.004Z",
"finishedAt": "2026-10-02T14:05:47.930Z",
"heartbeatAt": "2026-10-02T14:04:00.000Z",
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"search": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"cancel": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/cancel"
}
},
{
"id": "5b2d9f60-7c14-4a8e-b3d5-0e6f1a2c4d97",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "succeeded",
"step": "compliance",
"stepLabel": "Checking fair housing",
"attempts": 1,
"progress": {
"done": 9,
"total": 9,
"percent": 100
},
"createdAt": "2026-09-30T16:20:05.511Z",
"startedAt": "2026-09-30T16:20:05.511Z",
"finishedAt": "2026-09-30T16:22:41.087Z",
"heartbeatAt": "2026-10-02T14:04:00.000Z",
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/5b2d9f60-7c14-4a8e-b3d5-0e6f1a2c4d97",
"search": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"cancel": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/5b2d9f60-7c14-4a8e-b3d5-0e6f1a2c4d97/cancel"
}
}
],
"links": {
"next": null
}
}Fields (21)
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].id | string (uuid) | The run's id. |
data[].searchId | string (uuid) | |
data[].status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data[].step | "area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance" | null | The play the run is on, or null before it starts and after it ends. |
data[].stepLabel | string | null | That play in words for a person. |
data[].attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data[].progress | object | |
data[].progress.done | integer | Plays finished. |
data[].progress.total | integer | Plays in a run. |
data[].progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data[].createdAt | string (date-time) | |
data[].startedAt | string (date-time) | null | |
data[].finishedAt | string (date-time) | null | |
data[].heartbeatAt | string (date-time) | null | When the engine last checked in. Null before a claim. A running run that goes quiet here has stalled. |
data[].links | object | Where to read this run, its search, and where to POST to cancel it. |
data[].links.self | string | |
data[].links.search | string | |
data[].links.cancel | string | |
links | object | |
links.next | string | null | The URL of the next page, or null when this is the last. Follow it as given. |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search in your workspace. |
| 400 | invalid-cursor | The cursor is not one a page linked to. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Read a run
/api/v1/search/{searchId}/executions/{executionId}Status and results on one GET (headless path). Everything about one execution: where it is, each play it has taken, the calls it has made, and, once status is succeeded, its result (shortlist, excluded, funnel). Poll this same URL after kickoff until status is terminal; then read result on that response. Executions have no match — nothing appears in Searches or Clients. Prefer GET /api/v1/matches/{matchId} for the product path.
While the run is unfinished (queued or running) the answer carries Retry-After: 2. Wait that long between reads. Reading a run nobody is driving (a crash, a deadline, a deploy) picks it up again, so polling is what keeps a run moving.
result is frozen when the run finishes and never changes after the fact. result.notes lists every stand-in the run used, so a result is never passed off as live when part of it was not.
review counts what the engine's prose review did once the run finished: summary sentences it flagged, repaired or dropped, takes it rewrote, the repair calls it made. Each is a whole number, and a count a newer engine adds appears under its own name with no change to this API. It is null for a run whose engine sent none. The same counts are execution.review on GET /api/v1/runs/{runId}.
An API key carrying the scope named here, or a signed-in session.
- Scope
search:read- Key kinds
- PersonalOrganization
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
searchId | Path | string (uuid) | Required | The saved search's id. |
executionId | Path | string (uuid) | Required | The run's id: execution.id from the answer that queued it. |
Examples
curl "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
The run. result is null until it has succeeded.
HeadersRetry-After
{
"data": {
"id": "0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "succeeded",
"step": "compliance",
"stepLabel": "Checking fair housing",
"attempts": 1,
"progress": {
"done": 9,
"total": 9,
"percent": 100
},
"createdAt": "2026-10-02T14:03:12.118Z",
"startedAt": "2026-10-02T14:03:13.004Z",
"finishedAt": "2026-10-02T14:05:47.930Z",
"heartbeatAt": "2026-10-02T14:04:00.000Z",
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"search": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"cancel": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/cancel"
},
"engine": {
"kind": "cloud",
"algorithm": "v2",
"algorithmVersion": "2.0.0",
"prompts": [
{
"purpose": "weigh",
"version": 4,
"hash": "sha256:5f1c0e9a7b3d2c4e6f8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e",
"model": "google/gemini-3.1-flash-lite"
},
{
"purpose": "grade-text",
"version": 7,
"hash": "sha256:a3b9e2f4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5",
"model": "google/gemini-3.1-flash-lite"
},
{
"purpose": "summarize",
"version": null,
"hash": null,
"model": "google/gemini-3.1-flash-lite"
}
]
},
"services": {
"openrouter": "live",
"mls": "live",
"travel": "live",
"tavily": "live",
"places": "live",
"fair-housing": "live"
},
"steps": [
{
"name": "area",
"label": "Mapping where to look",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:13.018Z",
"finishedAt": "2026-10-02T14:03:22.018Z",
"durationMs": 9000,
"summary": {
"circles": 2
},
"progress": null,
"error": null
},
{
"name": "gather",
"label": "Gathering live listings",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:23.018Z",
"finishedAt": "2026-10-02T14:03:32.018Z",
"durationMs": 9000,
"summary": {
"fetched": 312
},
"progress": null,
"error": null
},
{
"name": "weigh",
"label": "Weighing what matters to them",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:33.018Z",
"finishedAt": "2026-10-02T14:03:42.018Z",
"durationMs": 9000,
"summary": {
"source": "model"
},
"progress": null,
"error": null
},
{
"name": "score",
"label": "Scoring every home",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:43.018Z",
"finishedAt": "2026-10-02T14:03:52.018Z",
"durationMs": 9000,
"summary": {
"scored": 155
},
"progress": null,
"error": null
},
{
"name": "enrich",
"label": "Checking neighborhoods",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:53.018Z",
"finishedAt": "2026-10-02T14:04:02.018Z",
"durationMs": 9000,
"summary": {
"checked": 25
},
"progress": null,
"error": null
},
{
"name": "inspire",
"label": "Studying the homes they liked",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:04:03.018Z",
"finishedAt": "2026-10-02T14:04:12.018Z",
"durationMs": 9000,
"summary": {
"references": 0
},
"progress": null,
"error": null
},
{
"name": "grade",
"label": "Reading each home's words and photos",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:04:13.018Z",
"finishedAt": "2026-10-02T14:04:22.018Z",
"durationMs": 9000,
"summary": {
"graded": 25
},
"progress": null,
"error": null
},
{
"name": "finalize",
"label": "Choosing the top homes",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:04:23.018Z",
"finishedAt": "2026-10-02T14:04:32.018Z",
"durationMs": 9000,
"summary": {
"shortlisted": 4
},
"progress": null,
"error": null
},
{
"name": "compliance",
"label": "Checking fair housing",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:04:33.018Z",
"finishedAt": "2026-10-02T14:04:42.018Z",
"durationMs": 9000,
"summary": {
"overall": "not_reviewed"
},
"progress": null,
"error": null
}
],
"usage": {
"calls": 94,
"failedCalls": 0,
"byService": [
{
"service": "openrouter",
"mode": "live",
"calls": 52,
"failed": 0,
"units": null,
"latencyMs": 61300
}
]
},
"checks": [
{
"step": "enrich",
"name": "listing has coordinates",
"severity": "warn",
"passed": 25,
"failed": 0,
"samples": []
}
],
"weights": {
"weights": {
"price": {
"lower": 450000,
"upper": 750000,
"weight": 9,
"decay": 0.000726,
"rationale": "The ceiling is firm."
},
"beds": {
"lower": 3,
"upper": 4,
"weight": 6,
"decay": 0.000726,
"rationale": null
},
"baths": {
"lower": 2,
"upper": 3,
"weight": 5,
"decay": 0.000726,
"rationale": null
},
"sqft": {
"lower": 1800,
"upper": 2600,
"weight": 4,
"decay": 0.000726,
"rationale": null
},
"travel": {
"lower": 0,
"upper": 1500,
"weight": 8,
"decay": 0.000726,
"rationale": "A short drive to the hospital matters most."
},
"priorityLocations": [
"East Nashville"
],
"propertyTypes": [
"single-family"
],
"rationale": "Budget and commute lead; the yard is a must.",
"realism": "realistic",
"adjustments": []
},
"source": "model",
"repairs": []
},
"weighHints": {
"hasCommute": true,
"hasSqft": true
},
"learned": {
"version": 1,
"asOf": "2026-10-02T15:00:00.000Z",
"votes": 6,
"lessons": [
{
"trait": "garage",
"direction": "toward",
"strength": 0.75,
"votes": 3
},
{
"trait": "needs_work",
"direction": "away",
"strength": 0.5,
"votes": 2
}
],
"comps": [],
"skipped": {
"guarded": 0,
"unread": 0
},
"resetAt": null
},
"area": {
"area": {
"circles": [
{
"label": "Downtown",
"latitude": 36.1627,
"longitude": -86.7816,
"km": 14.4,
"kind": "place"
}
],
"method": "estimated",
"rung": "circles"
},
"anchors": [
{
"id": "location_1",
"label": "Downtown",
"latitude": 36.1627,
"longitude": -86.7816,
"maxMinutes": 25
}
]
},
"result": {
"summary": {
"markdown": "Four homes fit the Okafors. **1204 Boscobel St** is the strongest: the yard, the porch and the short commute all land.",
"source": "model"
},
"shortlist": [
{
"rank": 1,
"listingKey": "NSH-2283104",
"address": "1204 Boscobel St",
"city": "Nashville",
"state": "TN",
"postalCode": "37206",
"neighbourhood": "East Nashville",
"price": 689000,
"beds": 3,
"baths": 2.5,
"sqft": 2140,
"yearBuilt": 1926,
"propertyType": "Residential",
"photo": "https://photos.example.com/NSH-2283104/hero.jpg",
"score": 91.4,
"scores": {
"math": 88.2,
"text": 93,
"photos": 92.5,
"neighbourhood": 90
},
"take": "A renovated 1926 bungalow with the fenced yard and the porch they asked for, 14 minutes from the hospital.",
"pros": [
"Fenced backyard",
"Walkable to two coffee shops",
"Dedicated home office"
],
"cons": [
"One bathroom is down a hallway from the primary"
],
"highlights": [
"Original heart-pine floors",
"Deep front porch"
],
"concerns": [],
"lookAndFeel": "Warm, bright, restored rather than flipped.",
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"minutes": 14,
"estimated": false
}
],
"signals": {
"school": 78,
"safety": 71
},
"breakdown": {
"price": 24.1,
"sqft": 18.5,
"beds": 9.2,
"baths": 9.6,
"travel": {
"location_1": 26.8
},
"bonuses": 0,
"total": 88.2
},
"blendWeights": {
"math": 0.4,
"text": 0.3,
"photos": 0.2,
"neighbourhood": 0.1
},
"officeName": "Hearth & Key Realty",
"unconfirmed": [
"two-car garage"
],
"confirmed": [
"fenced yard"
],
"keyPhotos": [
{
"url": "https://photos.example.com/NSH-2283104/kitchen.jpg",
"label": "Kitchen"
}
],
"gallery": [
"https://photos.example.com/NSH-2283104/hero.jpg",
"https://photos.example.com/NSH-2283104/kitchen.jpg"
]
}
],
"excluded": [
{
"rank": 5,
"listingKey": "NSH-2271550",
"address": "88 Gartland Ave",
"city": "Nashville",
"state": "TN",
"postalCode": "37206",
"neighbourhood": "East Nashville",
"price": 779000,
"beds": 3,
"baths": 2.5,
"sqft": 2140,
"yearBuilt": 1926,
"propertyType": "Residential",
"photo": "https://photos.example.com/NSH-2283104/hero.jpg",
"score": 66.1,
"scores": {
"math": 88.2,
"text": 93,
"photos": 92.5,
"neighbourhood": 90
},
"take": "A handsome home, just over budget.",
"pros": [
"Fenced backyard",
"Walkable to two coffee shops",
"Dedicated home office"
],
"cons": [
"One bathroom is down a hallway from the primary"
],
"highlights": [
"Original heart-pine floors",
"Deep front porch"
],
"concerns": [],
"lookAndFeel": "Warm, bright, restored rather than flipped.",
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"minutes": 14,
"estimated": false
}
],
"signals": {
"school": 78,
"safety": 71
},
"breakdown": {
"price": 24.1,
"sqft": 18.5,
"beds": 9.2,
"baths": 9.6,
"travel": {
"location_1": 26.8
},
"bonuses": 0,
"total": 88.2
},
"blendWeights": {
"math": 0.4,
"text": 0.3,
"photos": 0.2,
"neighbourhood": 0.1
},
"officeName": "Hearth & Key Realty",
"unconfirmed": [
"two-car garage"
],
"confirmed": [
"fenced yard"
],
"category": "over_budget",
"reason": "Asking $29,000 over the $750,000 budget."
}
],
"funnel": {
"terminalStatus": 12,
"noCoordinates": 3,
"outsideArea": 41,
"duplicates": 6,
"fetched": 312,
"wrongType": 38,
"pooled": 212,
"beyondReach": 57,
"scored": 155,
"graded": 25,
"shortlisted": 4
},
"rejected": {
"total": 21,
"byCategory": [
{
"category": "over_budget",
"label": "Over budget",
"count": 9,
"description": "More than 10% over $750,000."
}
]
},
"weights": {
"source": "model",
"realism": "realistic",
"rationale": "Budget and commute lead; the yard is a must.",
"adjustments": []
},
"market": {
"total": 312,
"medianPrice": 702500,
"medianSqft": 1980
},
"notes": [],
"credits": [
{
"text": "Routes by Targomo, map data by OpenStreetMap contributors.",
"url": "https://www.targomo.com"
}
],
"compliance": "not_reviewed"
},
"complianceSkip": null,
"review": {
"summaryFlagged": 2,
"summaryRepaired": 1,
"summaryDropped": 1,
"summarySectionsRebuilt": 0,
"proseFlagged": 1,
"proseRewritten": 1,
"takesStandIn": 0,
"repairCalls": 2
},
"error": null
}
}{
"data": {
"id": "0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "running",
"step": "grade",
"stepLabel": "Reading each home's words and photos",
"attempts": 1,
"progress": {
"done": 6,
"total": 9,
"percent": 71
},
"createdAt": "2026-10-02T14:03:12.118Z",
"startedAt": "2026-10-02T14:03:13.004Z",
"finishedAt": null,
"heartbeatAt": "2026-10-02T14:04:00.000Z",
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"search": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"cancel": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/cancel"
},
"engine": {
"kind": "cloud",
"algorithm": "v2",
"algorithmVersion": "2.0.0",
"prompts": [
{
"purpose": "weigh",
"version": 4,
"hash": "sha256:5f1c0e9a7b3d2c4e6f8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e",
"model": "google/gemini-3.1-flash-lite"
},
{
"purpose": "grade-text",
"version": 7,
"hash": "sha256:a3b9e2f4c6d8e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5",
"model": "google/gemini-3.1-flash-lite"
},
{
"purpose": "summarize",
"version": null,
"hash": null,
"model": "google/gemini-3.1-flash-lite"
}
]
},
"services": {
"openrouter": "live",
"mls": "live",
"travel": "live",
"tavily": "live",
"places": "live",
"fair-housing": "live"
},
"steps": [
{
"name": "area",
"label": "Mapping where to look",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:13.018Z",
"finishedAt": "2026-10-02T14:03:22.018Z",
"durationMs": 9000,
"summary": {
"circles": 2
},
"progress": null,
"error": null
},
{
"name": "gather",
"label": "Gathering live listings",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:23.018Z",
"finishedAt": "2026-10-02T14:03:32.018Z",
"durationMs": 9000,
"summary": {
"fetched": 312
},
"progress": null,
"error": null
},
{
"name": "weigh",
"label": "Weighing what matters to them",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:33.018Z",
"finishedAt": "2026-10-02T14:03:42.018Z",
"durationMs": 9000,
"summary": {
"source": "model"
},
"progress": null,
"error": null
},
{
"name": "score",
"label": "Scoring every home",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:43.018Z",
"finishedAt": "2026-10-02T14:03:52.018Z",
"durationMs": 9000,
"summary": {
"scored": 155
},
"progress": null,
"error": null
},
{
"name": "enrich",
"label": "Checking neighborhoods",
"status": "succeeded",
"attempt": 1,
"startedAt": "2026-10-02T14:03:53.018Z",
"finishedAt": "2026-10-02T14:04:02.018Z",
"durationMs": 9000,
"summary": {
"checked": 25
},
"progress": null,
"error": null
},
{
"name": "inspire",
"label": "Studying the homes they liked",
"status": "running",
"attempt": 1,
"startedAt": "2026-10-02T14:04:03.018Z",
"finishedAt": null,
"durationMs": null,
"summary": {
"references": 0
},
"progress": {
"done": 11,
"total": 25
},
"error": null
}
],
"usage": {
"calls": 61,
"failedCalls": 0,
"byService": [
{
"service": "openrouter",
"mode": "live",
"calls": 52,
"failed": 0,
"units": null,
"latencyMs": 61300
}
]
},
"checks": [],
"weights": {
"weights": {
"price": {
"lower": 450000,
"upper": 750000,
"weight": 9,
"decay": 0.000726,
"rationale": "The ceiling is firm."
},
"beds": {
"lower": 3,
"upper": 4,
"weight": 6,
"decay": 0.000726,
"rationale": null
},
"baths": {
"lower": 2,
"upper": 3,
"weight": 5,
"decay": 0.000726,
"rationale": null
},
"sqft": {
"lower": 1800,
"upper": 2600,
"weight": 4,
"decay": 0.000726,
"rationale": null
},
"travel": {
"lower": 0,
"upper": 1500,
"weight": 8,
"decay": 0.000726,
"rationale": "A short drive to the hospital matters most."
},
"priorityLocations": [
"East Nashville"
],
"propertyTypes": [
"single-family"
],
"rationale": "Budget and commute lead; the yard is a must.",
"realism": "realistic",
"adjustments": []
},
"source": "model",
"repairs": []
},
"weighHints": {
"hasCommute": true,
"hasSqft": true
},
"learned": {
"version": 1,
"asOf": "2026-10-02T15:00:00.000Z",
"votes": 6,
"lessons": [
{
"trait": "garage",
"direction": "toward",
"strength": 0.75,
"votes": 3
},
{
"trait": "needs_work",
"direction": "away",
"strength": 0.5,
"votes": 2
}
],
"comps": [],
"skipped": {
"guarded": 0,
"unread": 0
},
"resetAt": null
},
"area": null,
"result": null,
"complianceSkip": null,
"review": null,
"error": null
}
}{
"data": {
"id": "0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "queued",
"step": null,
"stepLabel": null,
"attempts": 0,
"progress": {
"done": 0,
"total": 9,
"percent": 0
},
"createdAt": "2026-10-02T14:03:12.118Z",
"startedAt": null,
"finishedAt": null,
"heartbeatAt": null,
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"search": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"cancel": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/cancel"
},
"engine": {
"kind": "cloud",
"algorithm": null,
"algorithmVersion": null,
"prompts": []
},
"services": {},
"steps": [],
"usage": {
"calls": 0,
"failedCalls": 0,
"byService": []
},
"checks": [],
"weights": null,
"weighHints": {
"hasCommute": true,
"hasSqft": true
},
"learned": null,
"area": null,
"result": null,
"complianceSkip": null,
"review": null,
"error": null
}
}Fields (342)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | The run's id. |
data.searchId | string (uuid) | |
data.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.step | "area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance" | null | The play the run is on, or null before it starts and after it ends. |
data.stepLabel | string | null | That play in words for a person. |
data.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.progress | object | |
data.progress.done | integer | Plays finished. |
data.progress.total | integer | Plays in a run. |
data.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.createdAt | string (date-time) | |
data.startedAt | string (date-time) | null | |
data.finishedAt | string (date-time) | null | |
data.heartbeatAt | string (date-time) | null | When the engine last checked in. Null before a claim. A running run that goes quiet here has stalled. |
data.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.links.self | string | |
data.links.search | string | |
data.links.cancel | string | |
data.engine | object | What answered this run. |
data.engine.kind | "builtin" | "cloud" | Which engine ran the run: cloud is the Python engine, builtin is this app's own. |
data.engine.algorithm | string | null | The algorithm the cloud engine used (v1 or v2). Null for a run on the built-in engine, or one the engine never claimed. |
data.engine.algorithmVersion | string | null | The version of that algorithm's behavior, like 2.0.0. It moves whenever what the algorithm would answer for a brief moves, so two runs with the same version answer alike. Null when algorithm is. |
data.engine.prompts | object[] | For each step of the match that called a model, the prompt it ran on and the model that answered. Steps the run never reached are left out. |
data.engine.prompts[].purpose | "weigh" | "grade-text" | "grade-photos" | "read-reference" | "summarize" | The step of a match the model call served: weigh, grade-text, grade-photos, read-reference or summarize. |
data.engine.prompts[].version | integer | null | The version of the prompt it ran on. Null for a call made before prompt versions were recorded. |
data.engine.prompts[].hash | string | null | sha256: and the hash of the prompt and model settings it ran on: two runs with the same hash ran on the same instructions. Null when unknown. |
data.engine.prompts[].model | string | null | The model that answered most of its calls. Null when the provider never said. |
data.services | object | Which outside services ran live and which ran as stand-ins, by service name. |
data.steps | object[] | |
data.steps[].name | "area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance" | |
data.steps[].label | string | |
data.steps[].status | "running" | "succeeded" | "failed" | "skipped" | |
data.steps[].attempt | integer | |
data.steps[].startedAt | string (date-time) | |
data.steps[].finishedAt | string (date-time) | null | |
data.steps[].durationMs | integer | null | |
data.steps[].summary | object | What the play counted. Keys differ by play and may grow. |
data.steps[].progress | object | null | How far a running play has got; null once it finished or when it counts nothing. |
data.steps[].progress.done | number | |
data.steps[].progress.total | number | |
data.steps[].error | object | null | |
data.steps[].error.code | string | |
data.steps[].error.digest | string | null | |
data.usage | object | |
data.usage.calls | integer | |
data.usage.failedCalls | integer | |
data.usage.inputTokens | integer, optional | Livia staff only. Tokens sent, across every service. Omitted unless the caller, or the key's maker, is Livia staff. |
data.usage.outputTokens | integer, optional | Livia staff only. Tokens received, across every service. Omitted unless the caller, or the key's maker, is Livia staff. |
data.usage.costUsd | object, optional | Livia staff only. Live dollars, apart from the projected dollars of stand-ins, which are never a charge. Omitted unless the caller, or the key's maker, is Livia staff. |
data.usage.costUsd.live | number | |
data.usage.costUsd.mockProjected | number | |
data.usage.byService | object[] | |
data.usage.byService[].service | "openrouter" | "tavily" | "mls" | "travel" | "places" | "fair-housing" | "compute" | "webhooks" | |
data.usage.byService[].mode | "live" | "mock" | live is a real provider; mock is a deterministic stand-in. |
data.usage.byService[].calls | integer | |
data.usage.byService[].failed | integer | |
data.usage.byService[].inputTokens | integer | null, optional | Livia staff only. Tokens sent; null when the provider reported none. Omitted unless the caller, or the key's maker, is Livia staff. |
data.usage.byService[].outputTokens | integer | null, optional | Livia staff only. Tokens received; null when the provider reported none. Omitted unless the caller, or the key's maker, is Livia staff. |
data.usage.byService[].units | number | null | |
data.usage.byService[].costUsd | number | null, optional | Livia staff only. Dollars, a projection for a stand-in; null when nobody priced the calls. Omitted unless the caller, or the key's maker, is Livia staff. |
data.usage.byService[].latencyMs | number | |
data.checks | object[] | Assumptions the run spot-checked, and how often each held. |
data.checks[].step | "area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance" | |
data.checks[].name | string | |
data.checks[].severity | "warn" | "error" | |
data.checks[].passed | integer | |
data.checks[].failed | integer | |
data.checks[].samples | any[] | |
data.weights | object | null | How Livia weighted this search. Null before the weigh play runs, or when an empty pool skipped it. |
data.weights.weights | object | |
data.weights.weights.price | object | |
data.weights.weights.price.lower | number | |
data.weights.weights.price.upper | number | |
data.weights.weights.price.weight | number | 0 to 10 |
data.weights.weights.price.decay | number | |
data.weights.weights.price.rationale | string | null | |
data.weights.weights.beds | object | |
data.weights.weights.beds.lower | number | |
data.weights.weights.beds.upper | number | |
data.weights.weights.beds.weight | number | 0 to 10 |
data.weights.weights.beds.decay | number | |
data.weights.weights.beds.rationale | string | null | |
data.weights.weights.baths | object | |
data.weights.weights.baths.lower | number | |
data.weights.weights.baths.upper | number | |
data.weights.weights.baths.weight | number | 0 to 10 |
data.weights.weights.baths.decay | number | |
data.weights.weights.baths.rationale | string | null | |
data.weights.weights.sqft | object | |
data.weights.weights.sqft.lower | number | |
data.weights.weights.sqft.upper | number | |
data.weights.weights.sqft.weight | number | 0 to 10 |
data.weights.weights.sqft.decay | number | |
data.weights.weights.sqft.rationale | string | null | |
data.weights.weights.travel | object | |
data.weights.weights.travel.lower | number | |
data.weights.weights.travel.upper | number | |
data.weights.weights.travel.weight | number | 0 to 10 |
data.weights.weights.travel.decay | number | |
data.weights.weights.travel.rationale | string | null | |
data.weights.weights.priorityLocations | string[] | |
data.weights.weights.propertyTypes | string[] | |
data.weights.weights.rationale | string | null | |
data.weights.weights.realism | "realistic" | "adjusted_minor" | "adjusted_major" | |
data.weights.weights.adjustments | string[] | |
data.weights.source | "model" | "placeholder" | |
data.weights.repairs | string[] | |
data.weighHints | object | |
data.weighHints.hasCommute | boolean | |
data.weighHints.hasSqft | boolean | |
data.area | object | null | Where the run looked. Null until the area step has run. |
data.area.area | object | |
data.area.area.circles | object[] | The circles a home may fall in; the fallback when a polygon could not be drawn. |
data.area.area.circles[].label | string | |
data.area.area.circles[].latitude | number | |
data.area.area.circles[].longitude | number | |
data.area.area.circles[].km | number | |
data.area.area.circles[].kind | "commute" | "place", optional | |
data.area.area.method | "estimated" | "routed" | |
data.area.area.shapes | object[], optional | Drive-time outlines when the travel service drew them. They replace the circles. |
data.area.area.shapes[].id | string | |
data.area.area.shapes[].label | string | |
data.area.area.shapes[].minutes | number | |
data.area.area.shapes[].polygons | any[][][][] | A multipolygon: polygons, each a list of rings (outer first, then holes) of [longitude, latitude] positions. |
data.area.area.shapeMode | "union" | "intersect", optional | union: a home in any outline counts. intersect: a home must be in all of them (commute destinations). |
data.area.area.rung | "pins" | "place" | "destinations" | "nashville" | "circles", optional | Which rung of the search-area ladder drew the area. |
data.area.area.note | "unreachable_together" | "thin_overlap" | "ceiling_capped", optional | |
data.area.area.preview | object[], optional | The commute's reach, drawn as a guide for a map. It is a preview: no home is ever filtered by it. |
data.area.area.preview[].id | string | |
data.area.area.preview[].label | string | |
data.area.area.preview[].minutes | number | |
data.area.area.preview[].polygons | any[][][][] | A multipolygon: polygons, each a list of rings (outer first, then holes) of [longitude, latitude] positions. |
data.area.anchors | object[] | The places travel was timed from, in priority order. |
data.area.anchors[].id | string | |
data.area.anchors[].label | string | |
data.area.anchors[].latitude | number | |
data.area.anchors[].longitude | number | |
data.area.anchors[].maxMinutes | number | null | |
data.learned | object | null | What the run learned from the agent's thumbs when it was queued. Null for a run from before learning. |
data.learned.version | 1 | |
data.learned.asOf | string | |
data.learned.votes | integer | |
data.learned.lessons | object[] | |
data.learned.lessons[].trait | "under_budget" | "at_budget" | "spacious" | "compact" | "extra_bedroom" | "extra_bath" | "big_lot" | "one_story" | "multi_story" | "garage" | "pool" | "hoa_free" | "has_hoa" | "newer_build" | "older_build" | "detached_house" | "condo" | "townhome" | "fireplace" | "hardwood" | "outdoor_living" | "fenced_yard" | "basement" | "open_plan" | "updated_kitchen" | "natural_light" | "modern_style" | "traditional_style" | "move_in_ready" | "needs_work" | |
data.learned.lessons[].direction | "toward" | "away" | |
data.learned.lessons[].strength | number | |
data.learned.lessons[].votes | integer | |
data.learned.comps | string[] | |
data.learned.skipped | object | |
data.learned.skipped.guarded | integer | |
data.learned.skipped.unread | integer | |
data.learned.resetAt | string | null | |
data.result | object | null | The answer, once the run has succeeded. Null until then. |
data.result.summary | object | |
data.result.summary.markdown | string | |
data.result.summary.source | "model" | "fallback" | |
data.result.shortlist | object[] | |
data.result.shortlist[].rank | integer | 1 is the best fit. |
data.result.shortlist[].listingKey | string | The MLS listing key. |
data.result.shortlist[].address | string | null | |
data.result.shortlist[].city | string | null | |
data.result.shortlist[].state | string | null | |
data.result.shortlist[].postalCode | string | null | |
data.result.shortlist[].neighbourhood | string | null | |
data.result.shortlist[].price | number | null | |
data.result.shortlist[].beds | number | null | |
data.result.shortlist[].baths | number | null | |
data.result.shortlist[].sqft | number | null | |
data.result.shortlist[].yearBuilt | number | null | |
data.result.shortlist[].propertyType | string | null | |
data.result.shortlist[].photo | string | null | The listing's hero photo URL. |
data.result.shortlist[].score | number | The blended score, two decimal places.0 to 100 |
data.result.shortlist[].scores | object | The parts of the score, each 0 to 100, or null where that part was not measured. |
data.result.shortlist[].scores.math | number | |
data.result.shortlist[].scores.text | number | null | |
data.result.shortlist[].scores.photos | number | null | |
data.result.shortlist[].scores.neighbourhood | number | null | |
data.result.shortlist[].take | string | One or two sentences on why this home fits, or does not. |
data.result.shortlist[].pros | string[] | |
data.result.shortlist[].cons | string[] | |
data.result.shortlist[].highlights | string[] | |
data.result.shortlist[].concerns | string[] | |
data.result.shortlist[].lookAndFeel | string | null | |
data.result.shortlist[].commutes | object[] | |
data.result.shortlist[].commutes[].label | string | |
data.result.shortlist[].commutes[].minutes | number | |
data.result.shortlist[].commutes[].estimated | boolean | True when the minutes were estimated rather than routed. |
data.result.shortlist[].signals | object | null | |
data.result.shortlist[].signals.school | number | null | |
data.result.shortlist[].signals.safety | number | null | |
data.result.shortlist[].breakdown | object | null | The math score, part by part. |
data.result.shortlist[].breakdown.price | number | |
data.result.shortlist[].breakdown.sqft | number | |
data.result.shortlist[].breakdown.beds | number | |
data.result.shortlist[].breakdown.baths | number | |
data.result.shortlist[].breakdown.travel | object | |
data.result.shortlist[].breakdown.bonuses | number | |
data.result.shortlist[].breakdown.total | number | |
data.result.shortlist[].blendWeights | object | null | Effective blend weights after missing axes redistribute. |
data.result.shortlist[].blendWeights.math | number | |
data.result.shortlist[].blendWeights.text | number | |
data.result.shortlist[].blendWeights.photos | number | |
data.result.shortlist[].blendWeights.neighbourhood | number | |
data.result.shortlist[].officeName | string | null | The listing broker. MLS rules require showing it beside the home. |
data.result.shortlist[].unconfirmed | string[] | The buyer's must-haves this listing never confirms, in their words. The summary never claims them. |
data.result.shortlist[].confirmed | string[] | The buyer's must-haves the listing or the engine's evidence confirms, in their words. Never one it leaves unconfirmed; empty when nothing was checked. |
data.result.shortlist[].keyPhotos | object[] | |
data.result.shortlist[].keyPhotos[].url | string | |
data.result.shortlist[].keyPhotos[].label | string | |
data.result.shortlist[].gallery | string[] | |
data.result.excluded | object[] | |
data.result.excluded[].rank | integer | 1 is the best fit. |
data.result.excluded[].listingKey | string | The MLS listing key. |
data.result.excluded[].address | string | null | |
data.result.excluded[].city | string | null | |
data.result.excluded[].state | string | null | |
data.result.excluded[].postalCode | string | null | |
data.result.excluded[].neighbourhood | string | null | |
data.result.excluded[].price | number | null | |
data.result.excluded[].beds | number | null | |
data.result.excluded[].baths | number | null | |
data.result.excluded[].sqft | number | null | |
data.result.excluded[].yearBuilt | number | null | |
data.result.excluded[].propertyType | string | null | |
data.result.excluded[].photo | string | null | The listing's hero photo URL. |
data.result.excluded[].score | number | The blended score, two decimal places.0 to 100 |
data.result.excluded[].scores | object | The parts of the score, each 0 to 100, or null where that part was not measured. |
data.result.excluded[].scores.math | number | |
data.result.excluded[].scores.text | number | null | |
data.result.excluded[].scores.photos | number | null | |
data.result.excluded[].scores.neighbourhood | number | null | |
data.result.excluded[].take | string | One or two sentences on why this home fits, or does not. |
data.result.excluded[].pros | string[] | |
data.result.excluded[].cons | string[] | |
data.result.excluded[].highlights | string[] | |
data.result.excluded[].concerns | string[] | |
data.result.excluded[].lookAndFeel | string | null | |
data.result.excluded[].commutes | object[] | |
data.result.excluded[].commutes[].label | string | |
data.result.excluded[].commutes[].minutes | number | |
data.result.excluded[].commutes[].estimated | boolean | True when the minutes were estimated rather than routed. |
data.result.excluded[].signals | object | null | |
data.result.excluded[].signals.school | number | null | |
data.result.excluded[].signals.safety | number | null | |
data.result.excluded[].breakdown | object | null | The math score, part by part. |
data.result.excluded[].breakdown.price | number | |
data.result.excluded[].breakdown.sqft | number | |
data.result.excluded[].breakdown.beds | number | |
data.result.excluded[].breakdown.baths | number | |
data.result.excluded[].breakdown.travel | object | |
data.result.excluded[].breakdown.bonuses | number | |
data.result.excluded[].breakdown.total | number | |
data.result.excluded[].blendWeights | object | null | Effective blend weights after missing axes redistribute. |
data.result.excluded[].blendWeights.math | number | |
data.result.excluded[].blendWeights.text | number | |
data.result.excluded[].blendWeights.photos | number | |
data.result.excluded[].blendWeights.neighbourhood | number | |
data.result.excluded[].officeName | string | null | The listing broker. MLS rules require showing it beside the home. |
data.result.excluded[].unconfirmed | string[] | The buyer's must-haves this listing never confirms, in their words. The summary never claims them. |
data.result.excluded[].confirmed | string[] | The buyer's must-haves the listing or the engine's evidence confirms, in their words. Never one it leaves unconfirmed; empty when nothing was checked. |
data.result.excluded[].category | "over_budget" | "below_specs" | "low_match" | "not_shortlisted" | |
data.result.excluded[].reason | string | |
data.result.excluded[].gallery | string[], optional | Up to 30 of the listing's photos, so a home added back to the shortlist shows them. A shortlisted home holds every photo it has. Absent on a run written before this was kept. |
data.result.funnel | object | How many homes each stage kept or dropped, from the source's answer to the shortlist. |
data.result.funnel.fetched | integer | |
data.result.funnel.wrongType | integer | |
data.result.funnel.pooled | integer | |
data.result.funnel.beyondReach | integer | |
data.result.funnel.scored | integer | |
data.result.funnel.graded | integer | |
data.result.funnel.shortlisted | integer | |
data.result.funnel.terminalStatus | integer | |
data.result.funnel.noCoordinates | integer | |
data.result.funnel.outsideArea | integer | |
data.result.funnel.duplicates | integer | |
data.result.rejected | object | |
data.result.rejected.total | integer | |
data.result.rejected.byCategory | object[] | |
data.result.rejected.byCategory[].category | "over_budget" | "below_specs" | "lower_score_match" | |
data.result.rejected.byCategory[].label | string | |
data.result.rejected.byCategory[].count | integer | |
data.result.rejected.byCategory[].description | string | |
data.result.weights | object | |
data.result.weights.source | "model" | "placeholder" | |
data.result.weights.realism | string | |
data.result.weights.rationale | string | null | |
data.result.weights.adjustments | string[] | |
data.result.market | object | |
data.result.market.total | integer | |
data.result.market.medianPrice | number | null | |
data.result.market.medianSqft | number | null | |
data.result.notes | string[] | A plain statement of every stand-in this run used. Empty only when everything was live. |
data.result.credits | object[] | Attribution a provider's terms require wherever the result is shown. |
data.result.credits[].text | string | |
data.result.credits[].url | string | |
data.result.compliance | "not_reviewed" | object | A fair housing checklist, or "not_reviewed" when the reviewer did not run. Never a clearance. |
data.result.compliance.kind | "checklist" | |
data.result.compliance.overall | "pass" | "warn" | "fail" | "needs_human" | |
data.result.compliance.items | object[] | |
data.result.compliance.items[].id | string | |
data.result.compliance.items[].status | "pass" | "warn" | "fail" | "info" | |
data.result.compliance.items[].detail | string | |
data.result.compliance.items[].check | string | |
data.result.compliance.items[].evidence | object[] | The exact words behind a flag, checked to be in the text they quote. A take's quote names its home. |
data.result.compliance.items[].evidence[].source | "brief" | "summary" | "take" | "exclusion" | |
data.result.compliance.items[].evidence[].listingKey | string | null | |
data.result.compliance.items[].evidence[].excerpt | string | |
data.result.compliance.reviewedAt | string | |
data.result.compliance.source | "model" | "stand-in" | |
data.result.learned | object, optional | What the run applied from the agent's thumbs: lessons, weights moved, homes reordered. Absent when it learned nothing. |
data.result.learned.lessons | object[] | |
data.result.learned.lessons[].trait | "under_budget" | "at_budget" | "spacious" | "compact" | "extra_bedroom" | "extra_bath" | "big_lot" | "one_story" | "multi_story" | "garage" | "pool" | "hoa_free" | "has_hoa" | "newer_build" | "older_build" | "detached_house" | "condo" | "townhome" | "fireplace" | "hardwood" | "outdoor_living" | "fenced_yard" | "basement" | "open_plan" | "updated_kitchen" | "natural_light" | "modern_style" | "traditional_style" | "move_in_ready" | "needs_work" | |
data.result.learned.lessons[].direction | "toward" | "away" | |
data.result.learned.lessons[].strength | number | |
data.result.learned.lessons[].votes | integer | |
data.result.learned.weights | object[] | |
data.result.learned.weights[].attribute | "price" | "sqft" | "beds" | "baths" | |
data.result.learned.weights[].direction | "more" | "less" | |
data.result.learned.weights[].by | number | |
data.result.learned.weights[].trait | "under_budget" | "at_budget" | "spacious" | "compact" | "extra_bedroom" | "extra_bath" | "big_lot" | "one_story" | "multi_story" | "garage" | "pool" | "hoa_free" | "has_hoa" | "newer_build" | "older_build" | "detached_house" | "condo" | "townhome" | "fireplace" | "hardwood" | "outdoor_living" | "fenced_yard" | "basement" | "open_plan" | "updated_kitchen" | "natural_light" | "modern_style" | "traditional_style" | "move_in_ready" | "needs_work" | |
data.result.learned.comps | integer | |
data.result.learned.tilted | object[] | |
data.result.learned.tilted[].listingKey | string | |
data.result.learned.tilted[].points | number | |
data.result.learned.tilted[].because | ("under_budget" | "at_budget" | "spacious" | "compact" | "extra_bedroom" | "extra_bath" | "big_lot" | "one_story" | "multi_story" | "garage" | "pool" | "hoa_free" | "has_hoa" | "newer_build" | "older_build" | "detached_house" | "condo" | "townhome" | "fireplace" | "hardwood" | "outdoor_living" | "fenced_yard" | "basement" | "open_plan" | "updated_kitchen" | "natural_light" | "modern_style" | "traditional_style" | "move_in_ready" | "needs_work")[] | |
data.result.learned.skipped | object | |
data.result.learned.skipped.guarded | integer | |
data.result.learned.skipped.unread | integer | |
data.result.fairHousing | object, optional | Phrases set aside from the brief before any prompt, by class (never the words), and phrases removed from what models wrote. Absent when neither. |
data.result.fairHousing.setAside | object[] | |
data.result.fairHousing.setAside[].category | "familial_status" | "race_or_origin" | "religion" | "disability" | "sex" | "source_of_income" | "who_lives_there" | |
data.result.fairHousing.setAside[].count | integer | |
data.result.fairHousing.removed | integer | |
data.complianceSkip | object | null | Why result.compliance stayed "not_reviewed". Null when a checklist ran or compliance has not finished. Fail-closed by design: an unusable reviewer reply never invents a pass. |
data.complianceSkip.reason | "off" | "not-configured" | "call-failed" | "no-homes" | "nothing-to-review" | null | Why the checklist did not run: off, not-configured, call-failed, no-homes, or nothing-to-review. Null on an older run that predates named reasons. |
data.complianceSkip.errorCode | string | null | The provider or schema error when reason is call-failed (for example bad-response). Null otherwise. |
data.complianceSkip.digest | string | null | A request id that finds the failed call's log lines when reason is call-failed. Null otherwise. |
data.review | object | null | What the engine's prose review did on this run, as whole-number counts by name: summaryFlagged, summaryRepaired, summaryDropped, summarySectionsRebuilt, proseFlagged, proseRewritten, takesStandIn, repairCalls, and any count a newer engine adds (its verify… counts). Counts only, never the prose. Null when the engine sent none; a run on the built-in engine never has one. |
data.error | object | null | Why a failed or canceled run stopped; null otherwise. |
data.error.code | string | |
data.error.digest | string | null |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search or run in your workspace. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Cancel a run
/api/v1/search/{searchId}/executions/{executionId}/cancelStops a queued or running run. The run is canceled at once and the answer is 202 with that final state. A play already in flight is abandoned at its next heartbeat, so a provider call already out may still finish. What the run spent so far stays on the ledger.
An API key carrying the scope named here, or a signed-in session.
- Scope
search:run- Key kinds
- PersonalOrganization
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
searchId | Path | string (uuid) | Required | The saved search's id. |
executionId | Path | string (uuid) | Required | The run's id: execution.id from the answer that queued it. |
Examples
curl -X POST "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/cancel" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
The run was canceled.
{
"data": {
"id": "0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "canceled",
"step": "grade",
"stepLabel": "Reading each home's words and photos",
"attempts": 1,
"progress": {
"done": 6,
"total": 9,
"percent": 71
},
"createdAt": "2026-10-02T14:03:12.118Z",
"startedAt": "2026-10-02T14:03:13.004Z",
"finishedAt": "2026-10-02T14:04:02.771Z",
"heartbeatAt": "2026-10-02T14:04:00.000Z",
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"search": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"cancel": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/cancel"
}
}
}Fields (19)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | The run's id. |
data.searchId | string (uuid) | |
data.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.step | "area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance" | null | The play the run is on, or null before it starts and after it ends. |
data.stepLabel | string | null | That play in words for a person. |
data.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.progress | object | |
data.progress.done | integer | Plays finished. |
data.progress.total | integer | Plays in a run. |
data.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.createdAt | string (date-time) | |
data.startedAt | string (date-time) | null | |
data.finishedAt | string (date-time) | null | |
data.heartbeatAt | string (date-time) | null | When the engine last checked in. Null before a claim. A running run that goes quiet here has stalled. |
data.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.links.self | string | |
data.links.search | string | |
data.links.cancel | string |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search or run in your workspace. |
| 409 | already-finished | The run had already succeeded, failed or been canceled. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Explore a run's pool
/api/v1/search/{searchId}/executions/{executionId}/candidatesEvery home the run considered, in math-ranking order, with what it learned about each: travel times, the math score, the grades, the blend, and where it landed. Use it to show why a home that is not on the shortlist missed it. A pool is kept 30 days after its run finishes; after that the run keeps its result and the pool answers 410.
An API key carrying the scope named here, or a signed-in session.
- Scope
search:read- Key kinds
- PersonalOrganization
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
searchId | Path | string (uuid) | Required | The saved search's id. |
executionId | Path | string (uuid) | Required | The run's id: execution.id from the answer that queued it. |
filter | Query | "all" | "graded" | "shortlisted" | "excluded" | Optional | Which slice of the pool: all (default), graded, shortlisted or excluded. A links.next keeps it. |
limit | Query | integer | Optional | How many to return: 1 to 50, 20 when absent. A number outside that range is clamped; text is ignored. |
cursor | Query | string | Optional | Where the last page ended: the cursor inside the previous page's links.next. Pass links as given; a cursor you edit is refused. |
Examples
curl "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/candidates" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
One page of the pool.
{
"data": [
{
"key": "NSH-2283104",
"rank": 3,
"mathScore": 88.2,
"travelSeconds": {
"location_1": 840
},
"graded": true,
"score": 91.4,
"finalRank": 1,
"outcome": "shortlisted",
"grades": {
"text": 93,
"photos": 92.5,
"neighbourhood": 90
},
"listing": {
"key": "NSH-2283104",
"status": "Active",
"mlsStatus": "Active",
"listingType": "buy",
"propertyType": "Residential",
"propertySubType": "Single Family Residence",
"address": "1204 Boscobel St",
"city": "Nashville",
"state": "TN",
"postalCode": "37206",
"subdivision": "Lockeland Springs",
"latitude": 36.1832,
"longitude": -86.7424,
"price": 689000,
"beds": 3,
"baths": 2.5,
"sqft": 2140,
"yearBuilt": 1926,
"daysOnMarket": 9,
"onMarketDate": "2026-09-23",
"modifiedAt": "2026-09-29T11:42:08Z",
"heroPhotoUrl": "https://photos.example.com/NSH-2283104/hero.jpg"
}
}
],
"links": {
"next": null
}
}Fields (38)
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].key | string | The MLS listing key. |
data[].rank | integer | null | Its place in the math ranking, 1 first; null when it could not be scored. |
data[].mathScore | number | null | |
data[].travelSeconds | object | null | Seconds from each travel anchor (location_1...), null where unreachable; null until timed. |
data[].graded | boolean | |
data[].score | number | null | The blended score, once the run finalized; null for the ungraded rest of the pool. |
data[].finalRank | integer | null | |
data[].outcome | "shortlisted" | "excluded" | null | |
data[].grades | object | null | Each grade 0 to 100, null where it failed or was not taken. Null for homes never graded. |
data[].grades.text | number | null | |
data[].grades.photos | number | null | |
data[].grades.neighbourhood | number | null | |
data[].listing | object | |
data[].listing.key | string | |
data[].listing.status | string | null | |
data[].listing.mlsStatus | string | null | |
data[].listing.listingType | "buy" | "rent" | |
data[].listing.propertyType | string | null | |
data[].listing.propertySubType | string | null | |
data[].listing.address | string | null | |
data[].listing.city | string | null | |
data[].listing.state | string | null | |
data[].listing.postalCode | string | null | |
data[].listing.subdivision | string | null | |
data[].listing.latitude | number | null | |
data[].listing.longitude | number | null | |
data[].listing.price | number | null | |
data[].listing.beds | number | null | |
data[].listing.baths | number | null | |
data[].listing.sqft | number | null | |
data[].listing.yearBuilt | number | null | |
data[].listing.daysOnMarket | number | null | |
data[].listing.onMarketDate | string | null | |
data[].listing.modifiedAt | string | null | |
data[].listing.heroPhotoUrl | string | null | |
links | object | |
links.next | string | null | The URL of the next page, or null when this is the last. Follow it as given. |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search or run in your workspace. |
| 400 | invalid | filter is not one of the four. |
| 400 | invalid-cursor | The cursor is not one a page linked to. |
| 410 | pool-expired | The run finished more than 30 days ago. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Download a match as a PDF
/api/v1/search-runs/{id}/pdfOne of your matches as a PDF, for your own systems. id is the match's, or the execution.id of the run that made it. It prints the match's live share as its client sees it, or, when none is live, the default package: every home on the shortlist, up to twenty, with the cover counting how many of how many when it holds more. Homes for sale print with the Realtracs and MLS GRID credits and their listing offices. X-Pdf-Engine says which engine printed, X-Pdf-Plain: 1 says when it is the plain version, and X-Pdf-Photos: 7/9 says how many photos printed of those wanted. The file is named for the brief and its top pick. A run started with an API key has no match, so it has no PDF.
An API key carrying the scope named here, or a signed-in session.
- Scope
search:read- Key kinds
- PersonalOrganization
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | Path | string (uuid) | Required | The match's id, or the id of the run that made it. |
Examples
curl "https://liviamatch.com/api/v1/search-runs/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83/pdf" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
The PDF's bytes, as an attachment, with X-Pdf-Engine, X-Pdf-Plain and X-Pdf-Photos.
The bytes, with their own content type.
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such match in your workspace, a run that has no match, or a malformed id. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal