Skip to the documentation

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

GET/api/v1/search/{searchId}/executions

The 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

NameInTypeRequiredDescription
searchIdPathstring (uuid)RequiredThe saved search's id.
limitQueryintegerOptionalHow many to return: 1 to 50, 20 when absent. A number outside that range is clamped; text is ignored.
cursorQuerystringOptionalWhere 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

200

One page of runs.

Two 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)
FieldTypeDescription
dataobject[]
data[].idstring (uuid)The run's id.
data[].searchIdstring (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" | nullThe play the run is on, or null before it starts and after it ends.
data[].stepLabelstring | nullThat play in words for a person.
data[].attemptsintegerHow many times a driver has claimed the run. More than one means it resumed after a crash or a deadline.
data[].progressobject
data[].progress.doneintegerPlays finished.
data[].progress.totalintegerPlays in a run.
data[].progress.percentintegerHow far along, 0 to 100. It moves inside a long play.0 to 100
data[].createdAtstring (date-time)
data[].startedAtstring (date-time) | null
data[].finishedAtstring (date-time) | null
data[].heartbeatAtstring (date-time) | nullWhen the engine last checked in. Null before a claim. A running run that goes quiet here has stalled.
data[].linksobjectWhere to read this run, its search, and where to POST to cancel it.
data[].links.selfstring
data[].links.searchstring
data[].links.cancelstring
linksobject
links.nextstring | nullThe URL of the next page, or null when this is the last. Follow it as given.

Errors

StatusCodeWhen
404not-foundNo such search in your workspace.
400invalid-cursorThe 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

GET/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

NameInTypeRequiredDescription
searchIdPathstring (uuid)RequiredThe saved search's id.
executionIdPathstring (uuid)RequiredThe 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

200

The run. result is null until it has succeeded.

HeadersRetry-After

A finished run
{
  "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
  }
}
A run still working
{
  "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
  }
}
A run just queued
{
  "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)
FieldTypeDescription
dataobject
data.idstring (uuid)The run's id.
data.searchIdstring (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" | nullThe play the run is on, or null before it starts and after it ends.
data.stepLabelstring | nullThat play in words for a person.
data.attemptsintegerHow many times a driver has claimed the run. More than one means it resumed after a crash or a deadline.
data.progressobject
data.progress.doneintegerPlays finished.
data.progress.totalintegerPlays in a run.
data.progress.percentintegerHow far along, 0 to 100. It moves inside a long play.0 to 100
data.createdAtstring (date-time)
data.startedAtstring (date-time) | null
data.finishedAtstring (date-time) | null
data.heartbeatAtstring (date-time) | nullWhen the engine last checked in. Null before a claim. A running run that goes quiet here has stalled.
data.linksobjectWhere to read this run, its search, and where to POST to cancel it.
data.links.selfstring
data.links.searchstring
data.links.cancelstring
data.engineobjectWhat 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.algorithmstring | nullThe 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.algorithmVersionstring | nullThe 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.promptsobject[]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[].versioninteger | nullThe version of the prompt it ran on. Null for a call made before prompt versions were recorded.
data.engine.prompts[].hashstring | nullsha256: 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[].modelstring | nullThe model that answered most of its calls. Null when the provider never said.
data.servicesobjectWhich outside services ran live and which ran as stand-ins, by service name.
data.stepsobject[]
data.steps[].name"area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance"
data.steps[].labelstring
data.steps[].status"running" | "succeeded" | "failed" | "skipped"
data.steps[].attemptinteger
data.steps[].startedAtstring (date-time)
data.steps[].finishedAtstring (date-time) | null
data.steps[].durationMsinteger | null
data.steps[].summaryobjectWhat the play counted. Keys differ by play and may grow.
data.steps[].progressobject | nullHow far a running play has got; null once it finished or when it counts nothing.
data.steps[].progress.donenumber
data.steps[].progress.totalnumber
data.steps[].errorobject | null
data.steps[].error.codestring
data.steps[].error.digeststring | null
data.usageobject
data.usage.callsinteger
data.usage.failedCallsinteger
data.usage.inputTokensinteger, optionalLivia staff only. Tokens sent, across every service. Omitted unless the caller, or the key's maker, is Livia staff.
data.usage.outputTokensinteger, optionalLivia staff only. Tokens received, across every service. Omitted unless the caller, or the key's maker, is Livia staff.
data.usage.costUsdobject, optionalLivia 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.livenumber
data.usage.costUsd.mockProjectednumber
data.usage.byServiceobject[]
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[].callsinteger
data.usage.byService[].failedinteger
data.usage.byService[].inputTokensinteger | null, optionalLivia 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[].outputTokensinteger | null, optionalLivia 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[].unitsnumber | null
data.usage.byService[].costUsdnumber | null, optionalLivia 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[].latencyMsnumber
data.checksobject[]Assumptions the run spot-checked, and how often each held.
data.checks[].step"area" | "gather" | "weigh" | "score" | "enrich" | "inspire" | "grade" | "finalize" | "compliance"
data.checks[].namestring
data.checks[].severity"warn" | "error"
data.checks[].passedinteger
data.checks[].failedinteger
data.checks[].samplesany[]
data.weightsobject | nullHow Livia weighted this search. Null before the weigh play runs, or when an empty pool skipped it.
data.weights.weightsobject
data.weights.weights.priceobject
data.weights.weights.price.lowernumber
data.weights.weights.price.uppernumber
data.weights.weights.price.weightnumber0 to 10
data.weights.weights.price.decaynumber
data.weights.weights.price.rationalestring | null
data.weights.weights.bedsobject
data.weights.weights.beds.lowernumber
data.weights.weights.beds.uppernumber
data.weights.weights.beds.weightnumber0 to 10
data.weights.weights.beds.decaynumber
data.weights.weights.beds.rationalestring | null
data.weights.weights.bathsobject
data.weights.weights.baths.lowernumber
data.weights.weights.baths.uppernumber
data.weights.weights.baths.weightnumber0 to 10
data.weights.weights.baths.decaynumber
data.weights.weights.baths.rationalestring | null
data.weights.weights.sqftobject
data.weights.weights.sqft.lowernumber
data.weights.weights.sqft.uppernumber
data.weights.weights.sqft.weightnumber0 to 10
data.weights.weights.sqft.decaynumber
data.weights.weights.sqft.rationalestring | null
data.weights.weights.travelobject
data.weights.weights.travel.lowernumber
data.weights.weights.travel.uppernumber
data.weights.weights.travel.weightnumber0 to 10
data.weights.weights.travel.decaynumber
data.weights.weights.travel.rationalestring | null
data.weights.weights.priorityLocationsstring[]
data.weights.weights.propertyTypesstring[]
data.weights.weights.rationalestring | null
data.weights.weights.realism"realistic" | "adjusted_minor" | "adjusted_major"
data.weights.weights.adjustmentsstring[]
data.weights.source"model" | "placeholder"
data.weights.repairsstring[]
data.weighHintsobject
data.weighHints.hasCommuteboolean
data.weighHints.hasSqftboolean
data.areaobject | nullWhere the run looked. Null until the area step has run.
data.area.areaobject
data.area.area.circlesobject[]The circles a home may fall in; the fallback when a polygon could not be drawn.
data.area.area.circles[].labelstring
data.area.area.circles[].latitudenumber
data.area.area.circles[].longitudenumber
data.area.area.circles[].kmnumber
data.area.area.circles[].kind"commute" | "place", optional
data.area.area.method"estimated" | "routed"
data.area.area.shapesobject[], optionalDrive-time outlines when the travel service drew them. They replace the circles.
data.area.area.shapes[].idstring
data.area.area.shapes[].labelstring
data.area.area.shapes[].minutesnumber
data.area.area.shapes[].polygonsany[][][][]A multipolygon: polygons, each a list of rings (outer first, then holes) of [longitude, latitude] positions.
data.area.area.shapeMode"union" | "intersect", optionalunion: 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", optionalWhich rung of the search-area ladder drew the area.
data.area.area.note"unreachable_together" | "thin_overlap" | "ceiling_capped", optional
data.area.area.previewobject[], optionalThe 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[].idstring
data.area.area.preview[].labelstring
data.area.area.preview[].minutesnumber
data.area.area.preview[].polygonsany[][][][]A multipolygon: polygons, each a list of rings (outer first, then holes) of [longitude, latitude] positions.
data.area.anchorsobject[]The places travel was timed from, in priority order.
data.area.anchors[].idstring
data.area.anchors[].labelstring
data.area.anchors[].latitudenumber
data.area.anchors[].longitudenumber
data.area.anchors[].maxMinutesnumber | null
data.learnedobject | nullWhat the run learned from the agent's thumbs when it was queued. Null for a run from before learning.
data.learned.version1
data.learned.asOfstring
data.learned.votesinteger
data.learned.lessonsobject[]
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[].strengthnumber
data.learned.lessons[].votesinteger
data.learned.compsstring[]
data.learned.skippedobject
data.learned.skipped.guardedinteger
data.learned.skipped.unreadinteger
data.learned.resetAtstring | null
data.resultobject | nullThe answer, once the run has succeeded. Null until then.
data.result.summaryobject
data.result.summary.markdownstring
data.result.summary.source"model" | "fallback"
data.result.shortlistobject[]
data.result.shortlist[].rankinteger1 is the best fit.
data.result.shortlist[].listingKeystringThe MLS listing key.
data.result.shortlist[].addressstring | null
data.result.shortlist[].citystring | null
data.result.shortlist[].statestring | null
data.result.shortlist[].postalCodestring | null
data.result.shortlist[].neighbourhoodstring | null
data.result.shortlist[].pricenumber | null
data.result.shortlist[].bedsnumber | null
data.result.shortlist[].bathsnumber | null
data.result.shortlist[].sqftnumber | null
data.result.shortlist[].yearBuiltnumber | null
data.result.shortlist[].propertyTypestring | null
data.result.shortlist[].photostring | nullThe listing's hero photo URL.
data.result.shortlist[].scorenumberThe blended score, two decimal places.0 to 100
data.result.shortlist[].scoresobjectThe parts of the score, each 0 to 100, or null where that part was not measured.
data.result.shortlist[].scores.mathnumber
data.result.shortlist[].scores.textnumber | null
data.result.shortlist[].scores.photosnumber | null
data.result.shortlist[].scores.neighbourhoodnumber | null
data.result.shortlist[].takestringOne or two sentences on why this home fits, or does not.
data.result.shortlist[].prosstring[]
data.result.shortlist[].consstring[]
data.result.shortlist[].highlightsstring[]
data.result.shortlist[].concernsstring[]
data.result.shortlist[].lookAndFeelstring | null
data.result.shortlist[].commutesobject[]
data.result.shortlist[].commutes[].labelstring
data.result.shortlist[].commutes[].minutesnumber
data.result.shortlist[].commutes[].estimatedbooleanTrue when the minutes were estimated rather than routed.
data.result.shortlist[].signalsobject | null
data.result.shortlist[].signals.schoolnumber | null
data.result.shortlist[].signals.safetynumber | null
data.result.shortlist[].breakdownobject | nullThe math score, part by part.
data.result.shortlist[].breakdown.pricenumber
data.result.shortlist[].breakdown.sqftnumber
data.result.shortlist[].breakdown.bedsnumber
data.result.shortlist[].breakdown.bathsnumber
data.result.shortlist[].breakdown.travelobject
data.result.shortlist[].breakdown.bonusesnumber
data.result.shortlist[].breakdown.totalnumber
data.result.shortlist[].blendWeightsobject | nullEffective blend weights after missing axes redistribute.
data.result.shortlist[].blendWeights.mathnumber
data.result.shortlist[].blendWeights.textnumber
data.result.shortlist[].blendWeights.photosnumber
data.result.shortlist[].blendWeights.neighbourhoodnumber
data.result.shortlist[].officeNamestring | nullThe listing broker. MLS rules require showing it beside the home.
data.result.shortlist[].unconfirmedstring[]The buyer's must-haves this listing never confirms, in their words. The summary never claims them.
data.result.shortlist[].confirmedstring[]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[].keyPhotosobject[]
data.result.shortlist[].keyPhotos[].urlstring
data.result.shortlist[].keyPhotos[].labelstring
data.result.shortlist[].gallerystring[]
data.result.excludedobject[]
data.result.excluded[].rankinteger1 is the best fit.
data.result.excluded[].listingKeystringThe MLS listing key.
data.result.excluded[].addressstring | null
data.result.excluded[].citystring | null
data.result.excluded[].statestring | null
data.result.excluded[].postalCodestring | null
data.result.excluded[].neighbourhoodstring | null
data.result.excluded[].pricenumber | null
data.result.excluded[].bedsnumber | null
data.result.excluded[].bathsnumber | null
data.result.excluded[].sqftnumber | null
data.result.excluded[].yearBuiltnumber | null
data.result.excluded[].propertyTypestring | null
data.result.excluded[].photostring | nullThe listing's hero photo URL.
data.result.excluded[].scorenumberThe blended score, two decimal places.0 to 100
data.result.excluded[].scoresobjectThe parts of the score, each 0 to 100, or null where that part was not measured.
data.result.excluded[].scores.mathnumber
data.result.excluded[].scores.textnumber | null
data.result.excluded[].scores.photosnumber | null
data.result.excluded[].scores.neighbourhoodnumber | null
data.result.excluded[].takestringOne or two sentences on why this home fits, or does not.
data.result.excluded[].prosstring[]
data.result.excluded[].consstring[]
data.result.excluded[].highlightsstring[]
data.result.excluded[].concernsstring[]
data.result.excluded[].lookAndFeelstring | null
data.result.excluded[].commutesobject[]
data.result.excluded[].commutes[].labelstring
data.result.excluded[].commutes[].minutesnumber
data.result.excluded[].commutes[].estimatedbooleanTrue when the minutes were estimated rather than routed.
data.result.excluded[].signalsobject | null
data.result.excluded[].signals.schoolnumber | null
data.result.excluded[].signals.safetynumber | null
data.result.excluded[].breakdownobject | nullThe math score, part by part.
data.result.excluded[].breakdown.pricenumber
data.result.excluded[].breakdown.sqftnumber
data.result.excluded[].breakdown.bedsnumber
data.result.excluded[].breakdown.bathsnumber
data.result.excluded[].breakdown.travelobject
data.result.excluded[].breakdown.bonusesnumber
data.result.excluded[].breakdown.totalnumber
data.result.excluded[].blendWeightsobject | nullEffective blend weights after missing axes redistribute.
data.result.excluded[].blendWeights.mathnumber
data.result.excluded[].blendWeights.textnumber
data.result.excluded[].blendWeights.photosnumber
data.result.excluded[].blendWeights.neighbourhoodnumber
data.result.excluded[].officeNamestring | nullThe listing broker. MLS rules require showing it beside the home.
data.result.excluded[].unconfirmedstring[]The buyer's must-haves this listing never confirms, in their words. The summary never claims them.
data.result.excluded[].confirmedstring[]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[].reasonstring
data.result.excluded[].gallerystring[], optionalUp 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.funnelobjectHow many homes each stage kept or dropped, from the source's answer to the shortlist.
data.result.funnel.fetchedinteger
data.result.funnel.wrongTypeinteger
data.result.funnel.pooledinteger
data.result.funnel.beyondReachinteger
data.result.funnel.scoredinteger
data.result.funnel.gradedinteger
data.result.funnel.shortlistedinteger
data.result.funnel.terminalStatusinteger
data.result.funnel.noCoordinatesinteger
data.result.funnel.outsideAreainteger
data.result.funnel.duplicatesinteger
data.result.rejectedobject
data.result.rejected.totalinteger
data.result.rejected.byCategoryobject[]
data.result.rejected.byCategory[].category"over_budget" | "below_specs" | "lower_score_match"
data.result.rejected.byCategory[].labelstring
data.result.rejected.byCategory[].countinteger
data.result.rejected.byCategory[].descriptionstring
data.result.weightsobject
data.result.weights.source"model" | "placeholder"
data.result.weights.realismstring
data.result.weights.rationalestring | null
data.result.weights.adjustmentsstring[]
data.result.marketobject
data.result.market.totalinteger
data.result.market.medianPricenumber | null
data.result.market.medianSqftnumber | null
data.result.notesstring[]A plain statement of every stand-in this run used. Empty only when everything was live.
data.result.creditsobject[]Attribution a provider's terms require wherever the result is shown.
data.result.credits[].textstring
data.result.credits[].urlstring
data.result.compliance"not_reviewed" | objectA 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.itemsobject[]
data.result.compliance.items[].idstring
data.result.compliance.items[].status"pass" | "warn" | "fail" | "info"
data.result.compliance.items[].detailstring
data.result.compliance.items[].checkstring
data.result.compliance.items[].evidenceobject[]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[].listingKeystring | null
data.result.compliance.items[].evidence[].excerptstring
data.result.compliance.reviewedAtstring
data.result.compliance.source"model" | "stand-in"
data.result.learnedobject, optionalWhat the run applied from the agent's thumbs: lessons, weights moved, homes reordered. Absent when it learned nothing.
data.result.learned.lessonsobject[]
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[].strengthnumber
data.result.learned.lessons[].votesinteger
data.result.learned.weightsobject[]
data.result.learned.weights[].attribute"price" | "sqft" | "beds" | "baths"
data.result.learned.weights[].direction"more" | "less"
data.result.learned.weights[].bynumber
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.compsinteger
data.result.learned.tiltedobject[]
data.result.learned.tilted[].listingKeystring
data.result.learned.tilted[].pointsnumber
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.skippedobject
data.result.learned.skipped.guardedinteger
data.result.learned.skipped.unreadinteger
data.result.fairHousingobject, optionalPhrases 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.setAsideobject[]
data.result.fairHousing.setAside[].category"familial_status" | "race_or_origin" | "religion" | "disability" | "sex" | "source_of_income" | "who_lives_there"
data.result.fairHousing.setAside[].countinteger
data.result.fairHousing.removedinteger
data.complianceSkipobject | nullWhy 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" | nullWhy 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.errorCodestring | nullThe provider or schema error when reason is call-failed (for example bad-response). Null otherwise.
data.complianceSkip.digeststring | nullA request id that finds the failed call's log lines when reason is call-failed. Null otherwise.
data.reviewobject | nullWhat 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.errorobject | nullWhy a failed or canceled run stopped; null otherwise.
data.error.codestring
data.error.digeststring | null

Errors

StatusCodeWhen
404not-foundNo 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

POST/api/v1/search/{searchId}/executions/{executionId}/cancel

Stops 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

NameInTypeRequiredDescription
searchIdPathstring (uuid)RequiredThe saved search's id.
executionIdPathstring (uuid)RequiredThe 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

202

The run was canceled.

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)
FieldTypeDescription
dataobject
data.idstring (uuid)The run's id.
data.searchIdstring (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" | nullThe play the run is on, or null before it starts and after it ends.
data.stepLabelstring | nullThat play in words for a person.
data.attemptsintegerHow many times a driver has claimed the run. More than one means it resumed after a crash or a deadline.
data.progressobject
data.progress.doneintegerPlays finished.
data.progress.totalintegerPlays in a run.
data.progress.percentintegerHow far along, 0 to 100. It moves inside a long play.0 to 100
data.createdAtstring (date-time)
data.startedAtstring (date-time) | null
data.finishedAtstring (date-time) | null
data.heartbeatAtstring (date-time) | nullWhen the engine last checked in. Null before a claim. A running run that goes quiet here has stalled.
data.linksobjectWhere to read this run, its search, and where to POST to cancel it.
data.links.selfstring
data.links.searchstring
data.links.cancelstring

Errors

StatusCodeWhen
404not-foundNo such search or run in your workspace.
409already-finishedThe 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

GET/api/v1/search/{searchId}/executions/{executionId}/candidates

Every 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

NameInTypeRequiredDescription
searchIdPathstring (uuid)RequiredThe saved search's id.
executionIdPathstring (uuid)RequiredThe run's id: execution.id from the answer that queued it.
filterQuery"all" | "graded" | "shortlisted" | "excluded"OptionalWhich slice of the pool: all (default), graded, shortlisted or excluded. A links.next keeps it.
limitQueryintegerOptionalHow many to return: 1 to 50, 20 when absent. A number outside that range is clamped; text is ignored.
cursorQuerystringOptionalWhere 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

200

One page of the pool.

One home, shortlisted
{
  "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)
FieldTypeDescription
dataobject[]
data[].keystringThe MLS listing key.
data[].rankinteger | nullIts place in the math ranking, 1 first; null when it could not be scored.
data[].mathScorenumber | null
data[].travelSecondsobject | nullSeconds from each travel anchor (location_1...), null where unreachable; null until timed.
data[].gradedboolean
data[].scorenumber | nullThe blended score, once the run finalized; null for the ungraded rest of the pool.
data[].finalRankinteger | null
data[].outcome"shortlisted" | "excluded" | null
data[].gradesobject | nullEach grade 0 to 100, null where it failed or was not taken. Null for homes never graded.
data[].grades.textnumber | null
data[].grades.photosnumber | null
data[].grades.neighbourhoodnumber | null
data[].listingobject
data[].listing.keystring
data[].listing.statusstring | null
data[].listing.mlsStatusstring | null
data[].listing.listingType"buy" | "rent"
data[].listing.propertyTypestring | null
data[].listing.propertySubTypestring | null
data[].listing.addressstring | null
data[].listing.citystring | null
data[].listing.statestring | null
data[].listing.postalCodestring | null
data[].listing.subdivisionstring | null
data[].listing.latitudenumber | null
data[].listing.longitudenumber | null
data[].listing.pricenumber | null
data[].listing.bedsnumber | null
data[].listing.bathsnumber | null
data[].listing.sqftnumber | null
data[].listing.yearBuiltnumber | null
data[].listing.daysOnMarketnumber | null
data[].listing.onMarketDatestring | null
data[].listing.modifiedAtstring | null
data[].listing.heroPhotoUrlstring | null
linksobject
links.nextstring | nullThe URL of the next page, or null when this is the last. Follow it as given.

Errors

StatusCodeWhen
404not-foundNo such search or run in your workspace.
400invalidfilter is not one of the four.
400invalid-cursorThe cursor is not one a page linked to.
410pool-expiredThe 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

GET/api/v1/search-runs/{id}/pdf

One 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

NameInTypeRequiredDescription
idPathstring (uuid)RequiredThe 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

200

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

StatusCodeWhen
404not-foundNo 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