Headless search
A request kept so it can run again. Results stay on the execution and do not appear under Searches or Clients.
Start a search
/api/v1/searchHeadless path. Saves a request and queues its first run. The run is an execution with no match: results stay on the execution only and do not appear in Searches or Clients. Prefer POST /api/v1/searches/{searchId}/matches when the work should show up in the app.
It answers 202 at once. Location is the execution to poll — GET that same URL until status is succeeded, failed or canceled, honoring Retry-After between reads. When succeeded, result (with shortlist) is on that same response. See Runs and polling.
Send an Idempotency-Key. A network error after you sent the request leaves you not knowing whether a run started, and a second run spends a second match. With the key, a retry replays the first answer instead.
A start counts one match against the org's monthly allowance and against the person's own limit, and the run is recorded against the key that started it.
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 |
|---|---|---|---|---|
Idempotency-Key | Header | string | Optional | A value of your own for this attempt. The same key with the same request replays the first answer (Idempotent-Replayed: true) and starts nothing new; the same key with a different request is 409. A key is remembered for as long as its run exists. |
Request body
The whole request. location, price.max, beds.min and baths.min are required, and so is a place to start from: a commute, a preferred area, or location.center. Unknown fields are refused, so a typo fails loudly.
Fields (87)
| Field | Type | Required | Description |
|---|---|---|---|
version | 1 | Optional | default 1 |
clientId | string (uuid) | null | Optional | default null |
label | string | null | Optional | 1 to 120 characters, default null |
listingType | "buy" | "rent" | Optional | default "buy" |
location | object | Required | |
location.label | string | Required | 1 to 120 characters |
location.center | object | Optional | |
location.center.lat | number | Required | -90 to 90 |
location.center.lng | number | Required | -180 to 180 |
price | object | Required | |
price.min | number | Optional | 0 to 100000000 |
price.max | number | Required | 0 to 100000000 |
price.budget | number | Optional | 0 to 100000000 |
beds | object | Required | |
beds.min | integer | Required | 0 to 20 |
beds.target | integer | Optional | 0 to 20 |
baths | object | Required | |
baths.min | number | Required | 0 to 20 |
baths.target | number | Optional | 0 to 20 |
sqft | object | Optional | |
sqft.min | number | Optional | 0 to 100000 |
sqft.max | number | Optional | 0 to 100000 |
propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | Optional | at most 6 items, default [] |
commutes | object[] | Optional | at most 3 items, default [] |
commutes[].label | string | Required | 1 to 80 characters |
commutes[].lat | number | Optional | -90 to 90 |
commutes[].lng | number | Optional | -180 to 180 |
commutes[].maxMinutes | integer | Required | 0 to 120 |
commutes[].anyOf | string | Optional | 1 to 80 characters |
pins | object[] | Optional | at most 4 items |
pins[].id | string | Required | 1 to 64 characters |
pins[].lat | number | Required | -90 to 90 |
pins[].lng | number | Required | -180 to 180 |
areas | object[] | Optional | at most 10 items, default [] |
areas[].name | string | Required | 1 to 80 characters |
areas[].lat | number | Required | -90 to 90 |
areas[].lng | number | Required | -180 to 180 |
areas[].weight | integer | Optional | 1 to 10, default 5 |
areas[].kind | "city" | "neighborhood" | Optional | |
areas[].radiusMiles | number | Optional | 0.25 to 25 |
mustHaves | string[] | Optional | at most 20 items, default [] |
niceToHaves | string[] | Optional | at most 20 items, default [] |
dealBreakers | string[] | Optional | at most 20 items, default [] |
idealHome | string | null | Optional | at most 4000 characters, default null |
idealHomeImportance | "nice" | "must" | Optional | |
dislikes | string | null | Optional | at most 2000 characters, default null |
movingReason | string | null | Optional | at most 500 characters, default null |
lifestyle | object | Optional | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
lifestyle.household | string | null | Optional | at most 120 characters, default null |
lifestyle.hasKids | boolean | null | Optional | default null |
lifestyle.kidsAges | string | null | Optional | at most 60 characters, default null |
lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | Optional | default null |
lifestyle.workFromHome | boolean | null | Optional | default null |
lifestyle.wfhDaysPerWeek | number | null | Optional | 0 to 7, default null |
lifestyle.noiseSensitive | boolean | null | Optional | default null |
lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | Optional | default null |
lifestyle.hasPets | boolean | null | Optional | default null |
lifestyle.petType | string | null | Optional | at most 60 characters, default null |
lifestyle.renovationTolerance | "none" | "minor" | "major" | null | Optional | default null |
lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | Optional | default null |
lifestyle.neighborhoodVibe | string | null | Optional | at most 200 characters, default null |
lifestyle.weekendLifestyle | string | null | Optional | at most 200 characters, default null |
neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | Optional | at most 6 items, default [] |
vibe | object | Optional | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
vibe.tags | string[] | Optional | at most 12 items, default [] |
vibe.urbanToQuiet | integer | Optional | 0 to 100, default 50 |
vibe.moveInToProject | integer | Optional | 0 to 100, default 50 |
tasteReactions | object[] | Optional | at most 23 items, default [] |
tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | Required | |
tasteReactions[].reaction | "love" | "pass" | Required | |
inspirations | object[] | Optional | 1 to 4 items |
inspirations[].listingKey | string | Optional | 1 to 100 characters |
inspirations[].address | string | Optional | 1 to 200 characters |
inspirations[].price | number | Optional | 0 to 100000000 |
inspirations[].beds | integer | Optional | 0 to 20 |
inspirations[].baths | number | Optional | 0 to 20 |
inspirations[].sqft | number | Optional | 0 to 100000 |
inspirations[].description | string | Optional | 1 to 300 characters |
inspirations[].styleSignals | string[] | Optional | at most 10 items |
inspirationImportance | "nice" | "must" | Optional | |
callbackUrl | string | Optional | 1 to 2000 characters |
includeComingSoon | boolean | Optional | default true |
onMarketSince | string (date) | null | Optional | default null |
options | object | Optional | default {"shortlist":4,"grade":25,"photos":8} |
options.shortlist | integer | Optional | 1 to 12, default 4 |
options.grade | integer | Optional | 1 to 40, default 25 |
options.photos | integer | Optional | 0 to 8, default 8 |
{
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"options": {
"shortlist": 4
}
}Examples
curl -X POST "https://liviamatch.com/api/v1/search" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Idempotency-Key: okafor-east-nashville-1" \
-H "Content-Type: application/json" \
-d '{
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"options": {
"shortlist": 4
}
}'Responses
The search was saved and a run queued. The same answer replays for a repeated Idempotency-Key.
HeadersLocationRetry-AfterIdempotent-Replayed
{
"data": {
"search": {
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"label": "Okafors, East Nashville",
"clientId": null,
"revision": 1,
"request": {
"version": 1,
"clientId": null,
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"areas": [],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"dislikes": null,
"movingReason": null,
"lifestyle": {
"household": null,
"hasKids": null,
"kidsAges": null,
"schoolPriority": null,
"workFromHome": null,
"wfhDaysPerWeek": null,
"noiseSensitive": null,
"yardImportance": null,
"hasPets": null,
"petType": null,
"renovationTolerance": null,
"hoaPreference": null,
"neighborhoodVibe": null,
"weekendLifestyle": null
},
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"vibe": {
"tags": [],
"urbanToQuiet": 50,
"moveInToProject": 50
},
"tasteReactions": [],
"includeComingSoon": true,
"onMarketSince": null,
"options": {
"shortlist": 4,
"grade": 25,
"photos": 8
}
},
"createdAt": "2026-10-02T14:03:11.402Z",
"updatedAt": "2026-10-02T14:03:11.402Z",
"latestExecution": {
"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"
}
},
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"run": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"executions": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions"
}
},
"execution": {
"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"
}
}
}
}Fields (138)
| Field | Type | Description |
|---|---|---|
data | object | |
data.search | object | |
data.search.id | string (uuid) | |
data.search.label | string | null | |
data.search.clientId | string (uuid) | null | |
data.search.revision | integer | Counts up on every save. The same number is the ETag.at least 1 |
data.search.request | object | The request as saved, every default filled in. |
data.search.request.version | 1 | default 1 |
data.search.request.clientId | string (uuid) | null | default null |
data.search.request.label | string | null | 1 to 120 characters, default null |
data.search.request.listingType | "buy" | "rent" | default "buy" |
data.search.request.location | object | |
data.search.request.location.label | string | 1 to 120 characters |
data.search.request.location.center | object, optional | |
data.search.request.location.center.lat | number | -90 to 90 |
data.search.request.location.center.lng | number | -180 to 180 |
data.search.request.price | object | |
data.search.request.price.min | number, optional | 0 to 100000000 |
data.search.request.price.max | number | 0 to 100000000 |
data.search.request.price.budget | number, optional | 0 to 100000000 |
data.search.request.beds | object | |
data.search.request.beds.min | integer | 0 to 20 |
data.search.request.beds.target | integer, optional | 0 to 20 |
data.search.request.baths | object | |
data.search.request.baths.min | number | 0 to 20 |
data.search.request.baths.target | number, optional | 0 to 20 |
data.search.request.sqft | object, optional | |
data.search.request.sqft.min | number, optional | 0 to 100000 |
data.search.request.sqft.max | number, optional | 0 to 100000 |
data.search.request.propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | at most 6 items, default [] |
data.search.request.commutes | object[] | at most 3 items, default [] |
data.search.request.commutes[].label | string | 1 to 80 characters |
data.search.request.commutes[].lat | number, optional | -90 to 90 |
data.search.request.commutes[].lng | number, optional | -180 to 180 |
data.search.request.commutes[].maxMinutes | integer | 0 to 120 |
data.search.request.commutes[].anyOf | string, optional | 1 to 80 characters |
data.search.request.pins | object[], optional | at most 4 items |
data.search.request.pins[].id | string | 1 to 64 characters |
data.search.request.pins[].lat | number | -90 to 90 |
data.search.request.pins[].lng | number | -180 to 180 |
data.search.request.areas | object[] | at most 10 items, default [] |
data.search.request.areas[].name | string | 1 to 80 characters |
data.search.request.areas[].lat | number | -90 to 90 |
data.search.request.areas[].lng | number | -180 to 180 |
data.search.request.areas[].weight | integer | 1 to 10, default 5 |
data.search.request.areas[].kind | "city" | "neighborhood", optional | |
data.search.request.areas[].radiusMiles | number, optional | 0.25 to 25 |
data.search.request.mustHaves | string[] | at most 20 items, default [] |
data.search.request.niceToHaves | string[] | at most 20 items, default [] |
data.search.request.dealBreakers | string[] | at most 20 items, default [] |
data.search.request.idealHome | string | null | at most 4000 characters, default null |
data.search.request.idealHomeImportance | "nice" | "must", optional | |
data.search.request.dislikes | string | null | at most 2000 characters, default null |
data.search.request.movingReason | string | null | at most 500 characters, default null |
data.search.request.lifestyle | object | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
data.search.request.lifestyle.household | string | null | at most 120 characters, default null |
data.search.request.lifestyle.hasKids | boolean | null | default null |
data.search.request.lifestyle.kidsAges | string | null | at most 60 characters, default null |
data.search.request.lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | default null |
data.search.request.lifestyle.workFromHome | boolean | null | default null |
data.search.request.lifestyle.wfhDaysPerWeek | number | null | 0 to 7, default null |
data.search.request.lifestyle.noiseSensitive | boolean | null | default null |
data.search.request.lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | default null |
data.search.request.lifestyle.hasPets | boolean | null | default null |
data.search.request.lifestyle.petType | string | null | at most 60 characters, default null |
data.search.request.lifestyle.renovationTolerance | "none" | "minor" | "major" | null | default null |
data.search.request.lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | default null |
data.search.request.lifestyle.neighborhoodVibe | string | null | at most 200 characters, default null |
data.search.request.lifestyle.weekendLifestyle | string | null | at most 200 characters, default null |
data.search.request.neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | at most 6 items, default [] |
data.search.request.vibe | object | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
data.search.request.vibe.tags | string[] | at most 12 items, default [] |
data.search.request.vibe.urbanToQuiet | integer | 0 to 100, default 50 |
data.search.request.vibe.moveInToProject | integer | 0 to 100, default 50 |
data.search.request.tasteReactions | object[] | at most 23 items, default [] |
data.search.request.tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | |
data.search.request.tasteReactions[].reaction | "love" | "pass" | |
data.search.request.inspirations | object[], optional | 1 to 4 items |
data.search.request.inspirations[].listingKey | string, optional | 1 to 100 characters |
data.search.request.inspirations[].address | string, optional | 1 to 200 characters |
data.search.request.inspirations[].price | number, optional | 0 to 100000000 |
data.search.request.inspirations[].beds | integer, optional | 0 to 20 |
data.search.request.inspirations[].baths | number, optional | 0 to 20 |
data.search.request.inspirations[].sqft | number, optional | 0 to 100000 |
data.search.request.inspirations[].description | string, optional | 1 to 300 characters |
data.search.request.inspirations[].styleSignals | string[], optional | at most 10 items |
data.search.request.inspirationImportance | "nice" | "must", optional | |
data.search.request.callbackUrl | string, optional | 1 to 2000 characters |
data.search.request.includeComingSoon | boolean | default true |
data.search.request.onMarketSince | string (date) | null | default null |
data.search.request.options | object | default {"shortlist":4,"grade":25,"photos":8} |
data.search.request.options.shortlist | integer | 1 to 12, default 4 |
data.search.request.options.grade | integer | 1 to 40, default 25 |
data.search.request.options.photos | integer | 0 to 8, default 8 |
data.search.createdAt | string (date-time) | |
data.search.updatedAt | string (date-time) | |
data.search.latestExecution | object | null | The newest run, or null when the search was saved and never run. |
data.search.latestExecution.id | string (uuid) | The run's id. |
data.search.latestExecution.searchId | string (uuid) | |
data.search.latestExecution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.search.latestExecution.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.search.latestExecution.stepLabel | string | null | That play in words for a person. |
data.search.latestExecution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.search.latestExecution.progress | object | |
data.search.latestExecution.progress.done | integer | Plays finished. |
data.search.latestExecution.progress.total | integer | Plays in a run. |
data.search.latestExecution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.search.latestExecution.createdAt | string (date-time) | |
data.search.latestExecution.startedAt | string (date-time) | null | |
data.search.latestExecution.finishedAt | string (date-time) | null | |
data.search.latestExecution.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.search.latestExecution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.search.latestExecution.links.self | string | |
data.search.latestExecution.links.search | string | |
data.search.latestExecution.links.cancel | string | |
data.search.links | object | |
data.search.links.self | string | |
data.search.links.run | string | |
data.search.links.executions | string | |
data.execution | object | |
data.execution.id | string (uuid) | The run's id. |
data.execution.searchId | string (uuid) | |
data.execution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.execution.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.execution.stepLabel | string | null | That play in words for a person. |
data.execution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.execution.progress | object | |
data.execution.progress.done | integer | Plays finished. |
data.execution.progress.total | integer | Plays in a run. |
data.execution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.execution.createdAt | string (date-time) | |
data.execution.startedAt | string (date-time) | null | |
data.execution.finishedAt | string (date-time) | null | |
data.execution.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.execution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.execution.links.self | string | |
data.execution.links.search | string | |
data.execution.links.cancel | string |
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid | The request failed validation; issues names each field. |
| 400 | invalid-json | The body is not JSON. |
| 400 | invalid-idempotency-key | The Idempotency-Key is malformed. |
| 402 | out-of-credits | The org has no matches left this month. |
| 402 | person-limit-reached | The person the key acts as has used their own monthly matches. |
| 409 | idempotency-key-reused | The Idempotency-Key was used for a different request. |
| 413 | too-large | The body is over 64 KiB. |
| 422 | unknown-client | clientId is not a client in the workspace. |
| 422 | callback-url-refused | The callbackUrl is plain http to localhost on a deployment that is not development. |
| 422 | callback-needs-key | The run names a callbackUrl but was started without an API key. |
| 422 | no-signing-secret | The run names a callbackUrl and the key has no signing secret. |
| 429 | rate-limited | The hourly cap on starting runs is spent (the answer has no RateLimit header). |
| 429 | too-many-active | 3 runs are already queued or running. |
| 503 | search-unavailable | An outside service the run needs is not configured here. |
| 503 | studio-incomplete | A prompt the match engine runs is incomplete in Livia's AI settings; issues names the step. Nothing was started or spent. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 monthly-cap-reached500 internal
List searches
/api/v1/searchThe caller's saved searches, newest first, each with its newest run. Pages by cursor: follow links.next until it is null.
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 |
|---|---|---|---|---|
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" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
One page of searches.
{
"data": [
{
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"label": "Okafors, East Nashville",
"clientId": null,
"revision": 1,
"request": {
"version": 1,
"clientId": null,
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"areas": [],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"dislikes": null,
"movingReason": null,
"lifestyle": {
"household": null,
"hasKids": null,
"kidsAges": null,
"schoolPriority": null,
"workFromHome": null,
"wfhDaysPerWeek": null,
"noiseSensitive": null,
"yardImportance": null,
"hasPets": null,
"petType": null,
"renovationTolerance": null,
"hoaPreference": null,
"neighborhoodVibe": null,
"weekendLifestyle": null
},
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"vibe": {
"tags": [],
"urbanToQuiet": 50,
"moveInToProject": 50
},
"tasteReactions": [],
"includeComingSoon": true,
"onMarketSince": null,
"options": {
"shortlist": 4,
"grade": 25,
"photos": 8
}
},
"createdAt": "2026-10-02T14:03:11.402Z",
"updatedAt": "2026-10-02T14:03:11.402Z",
"latestExecution": {
"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"
}
},
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"run": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"executions": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions"
}
}
],
"links": {
"next": null
}
}Fields (120)
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].id | string (uuid) | |
data[].label | string | null | |
data[].clientId | string (uuid) | null | |
data[].revision | integer | Counts up on every save. The same number is the ETag.at least 1 |
data[].request | object | The request as saved, every default filled in. |
data[].request.version | 1 | default 1 |
data[].request.clientId | string (uuid) | null | default null |
data[].request.label | string | null | 1 to 120 characters, default null |
data[].request.listingType | "buy" | "rent" | default "buy" |
data[].request.location | object | |
data[].request.location.label | string | 1 to 120 characters |
data[].request.location.center | object, optional | |
data[].request.location.center.lat | number | -90 to 90 |
data[].request.location.center.lng | number | -180 to 180 |
data[].request.price | object | |
data[].request.price.min | number, optional | 0 to 100000000 |
data[].request.price.max | number | 0 to 100000000 |
data[].request.price.budget | number, optional | 0 to 100000000 |
data[].request.beds | object | |
data[].request.beds.min | integer | 0 to 20 |
data[].request.beds.target | integer, optional | 0 to 20 |
data[].request.baths | object | |
data[].request.baths.min | number | 0 to 20 |
data[].request.baths.target | number, optional | 0 to 20 |
data[].request.sqft | object, optional | |
data[].request.sqft.min | number, optional | 0 to 100000 |
data[].request.sqft.max | number, optional | 0 to 100000 |
data[].request.propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | at most 6 items, default [] |
data[].request.commutes | object[] | at most 3 items, default [] |
data[].request.commutes[].label | string | 1 to 80 characters |
data[].request.commutes[].lat | number, optional | -90 to 90 |
data[].request.commutes[].lng | number, optional | -180 to 180 |
data[].request.commutes[].maxMinutes | integer | 0 to 120 |
data[].request.commutes[].anyOf | string, optional | 1 to 80 characters |
data[].request.pins | object[], optional | at most 4 items |
data[].request.pins[].id | string | 1 to 64 characters |
data[].request.pins[].lat | number | -90 to 90 |
data[].request.pins[].lng | number | -180 to 180 |
data[].request.areas | object[] | at most 10 items, default [] |
data[].request.areas[].name | string | 1 to 80 characters |
data[].request.areas[].lat | number | -90 to 90 |
data[].request.areas[].lng | number | -180 to 180 |
data[].request.areas[].weight | integer | 1 to 10, default 5 |
data[].request.areas[].kind | "city" | "neighborhood", optional | |
data[].request.areas[].radiusMiles | number, optional | 0.25 to 25 |
data[].request.mustHaves | string[] | at most 20 items, default [] |
data[].request.niceToHaves | string[] | at most 20 items, default [] |
data[].request.dealBreakers | string[] | at most 20 items, default [] |
data[].request.idealHome | string | null | at most 4000 characters, default null |
data[].request.idealHomeImportance | "nice" | "must", optional | |
data[].request.dislikes | string | null | at most 2000 characters, default null |
data[].request.movingReason | string | null | at most 500 characters, default null |
data[].request.lifestyle | object | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
data[].request.lifestyle.household | string | null | at most 120 characters, default null |
data[].request.lifestyle.hasKids | boolean | null | default null |
data[].request.lifestyle.kidsAges | string | null | at most 60 characters, default null |
data[].request.lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | default null |
data[].request.lifestyle.workFromHome | boolean | null | default null |
data[].request.lifestyle.wfhDaysPerWeek | number | null | 0 to 7, default null |
data[].request.lifestyle.noiseSensitive | boolean | null | default null |
data[].request.lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | default null |
data[].request.lifestyle.hasPets | boolean | null | default null |
data[].request.lifestyle.petType | string | null | at most 60 characters, default null |
data[].request.lifestyle.renovationTolerance | "none" | "minor" | "major" | null | default null |
data[].request.lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | default null |
data[].request.lifestyle.neighborhoodVibe | string | null | at most 200 characters, default null |
data[].request.lifestyle.weekendLifestyle | string | null | at most 200 characters, default null |
data[].request.neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | at most 6 items, default [] |
data[].request.vibe | object | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
data[].request.vibe.tags | string[] | at most 12 items, default [] |
data[].request.vibe.urbanToQuiet | integer | 0 to 100, default 50 |
data[].request.vibe.moveInToProject | integer | 0 to 100, default 50 |
data[].request.tasteReactions | object[] | at most 23 items, default [] |
data[].request.tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | |
data[].request.tasteReactions[].reaction | "love" | "pass" | |
data[].request.inspirations | object[], optional | 1 to 4 items |
data[].request.inspirations[].listingKey | string, optional | 1 to 100 characters |
data[].request.inspirations[].address | string, optional | 1 to 200 characters |
data[].request.inspirations[].price | number, optional | 0 to 100000000 |
data[].request.inspirations[].beds | integer, optional | 0 to 20 |
data[].request.inspirations[].baths | number, optional | 0 to 20 |
data[].request.inspirations[].sqft | number, optional | 0 to 100000 |
data[].request.inspirations[].description | string, optional | 1 to 300 characters |
data[].request.inspirations[].styleSignals | string[], optional | at most 10 items |
data[].request.inspirationImportance | "nice" | "must", optional | |
data[].request.callbackUrl | string, optional | 1 to 2000 characters |
data[].request.includeComingSoon | boolean | default true |
data[].request.onMarketSince | string (date) | null | default null |
data[].request.options | object | default {"shortlist":4,"grade":25,"photos":8} |
data[].request.options.shortlist | integer | 1 to 12, default 4 |
data[].request.options.grade | integer | 1 to 40, default 25 |
data[].request.options.photos | integer | 0 to 8, default 8 |
data[].createdAt | string (date-time) | |
data[].updatedAt | string (date-time) | |
data[].latestExecution | object | null | The newest run, or null when the search was saved and never run. |
data[].latestExecution.id | string (uuid) | The run's id. |
data[].latestExecution.searchId | string (uuid) | |
data[].latestExecution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data[].latestExecution.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[].latestExecution.stepLabel | string | null | That play in words for a person. |
data[].latestExecution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data[].latestExecution.progress | object | |
data[].latestExecution.progress.done | integer | Plays finished. |
data[].latestExecution.progress.total | integer | Plays in a run. |
data[].latestExecution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data[].latestExecution.createdAt | string (date-time) | |
data[].latestExecution.startedAt | string (date-time) | null | |
data[].latestExecution.finishedAt | string (date-time) | null | |
data[].latestExecution.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[].latestExecution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data[].latestExecution.links.self | string | |
data[].latestExecution.links.search | string | |
data[].latestExecution.links.cancel | string | |
data[].links | object | |
data[].links.self | string | |
data[].links.run | string | |
data[].links.executions | 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 |
|---|---|---|
| 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 search
/api/v1/search/{searchId}One saved search and its newest run. The ETag is the search's revision; send it back as If-Match to change or delete the search without overwriting a change you have not seen.
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. |
Examples
curl "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
The search.
HeadersETag
{
"data": {
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"label": "Okafors, East Nashville",
"clientId": null,
"revision": 1,
"request": {
"version": 1,
"clientId": null,
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"areas": [],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"dislikes": null,
"movingReason": null,
"lifestyle": {
"household": null,
"hasKids": null,
"kidsAges": null,
"schoolPriority": null,
"workFromHome": null,
"wfhDaysPerWeek": null,
"noiseSensitive": null,
"yardImportance": null,
"hasPets": null,
"petType": null,
"renovationTolerance": null,
"hoaPreference": null,
"neighborhoodVibe": null,
"weekendLifestyle": null
},
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"vibe": {
"tags": [],
"urbanToQuiet": 50,
"moveInToProject": 50
},
"tasteReactions": [],
"includeComingSoon": true,
"onMarketSince": null,
"options": {
"shortlist": 4,
"grade": 25,
"photos": 8
}
},
"createdAt": "2026-10-02T14:03:11.402Z",
"updatedAt": "2026-10-02T14:03:11.402Z",
"latestExecution": {
"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"
}
},
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"run": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"executions": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions"
}
}
}Fields (118)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.label | string | null | |
data.clientId | string (uuid) | null | |
data.revision | integer | Counts up on every save. The same number is the ETag.at least 1 |
data.request | object | The request as saved, every default filled in. |
data.request.version | 1 | default 1 |
data.request.clientId | string (uuid) | null | default null |
data.request.label | string | null | 1 to 120 characters, default null |
data.request.listingType | "buy" | "rent" | default "buy" |
data.request.location | object | |
data.request.location.label | string | 1 to 120 characters |
data.request.location.center | object, optional | |
data.request.location.center.lat | number | -90 to 90 |
data.request.location.center.lng | number | -180 to 180 |
data.request.price | object | |
data.request.price.min | number, optional | 0 to 100000000 |
data.request.price.max | number | 0 to 100000000 |
data.request.price.budget | number, optional | 0 to 100000000 |
data.request.beds | object | |
data.request.beds.min | integer | 0 to 20 |
data.request.beds.target | integer, optional | 0 to 20 |
data.request.baths | object | |
data.request.baths.min | number | 0 to 20 |
data.request.baths.target | number, optional | 0 to 20 |
data.request.sqft | object, optional | |
data.request.sqft.min | number, optional | 0 to 100000 |
data.request.sqft.max | number, optional | 0 to 100000 |
data.request.propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | at most 6 items, default [] |
data.request.commutes | object[] | at most 3 items, default [] |
data.request.commutes[].label | string | 1 to 80 characters |
data.request.commutes[].lat | number, optional | -90 to 90 |
data.request.commutes[].lng | number, optional | -180 to 180 |
data.request.commutes[].maxMinutes | integer | 0 to 120 |
data.request.commutes[].anyOf | string, optional | 1 to 80 characters |
data.request.pins | object[], optional | at most 4 items |
data.request.pins[].id | string | 1 to 64 characters |
data.request.pins[].lat | number | -90 to 90 |
data.request.pins[].lng | number | -180 to 180 |
data.request.areas | object[] | at most 10 items, default [] |
data.request.areas[].name | string | 1 to 80 characters |
data.request.areas[].lat | number | -90 to 90 |
data.request.areas[].lng | number | -180 to 180 |
data.request.areas[].weight | integer | 1 to 10, default 5 |
data.request.areas[].kind | "city" | "neighborhood", optional | |
data.request.areas[].radiusMiles | number, optional | 0.25 to 25 |
data.request.mustHaves | string[] | at most 20 items, default [] |
data.request.niceToHaves | string[] | at most 20 items, default [] |
data.request.dealBreakers | string[] | at most 20 items, default [] |
data.request.idealHome | string | null | at most 4000 characters, default null |
data.request.idealHomeImportance | "nice" | "must", optional | |
data.request.dislikes | string | null | at most 2000 characters, default null |
data.request.movingReason | string | null | at most 500 characters, default null |
data.request.lifestyle | object | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
data.request.lifestyle.household | string | null | at most 120 characters, default null |
data.request.lifestyle.hasKids | boolean | null | default null |
data.request.lifestyle.kidsAges | string | null | at most 60 characters, default null |
data.request.lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | default null |
data.request.lifestyle.workFromHome | boolean | null | default null |
data.request.lifestyle.wfhDaysPerWeek | number | null | 0 to 7, default null |
data.request.lifestyle.noiseSensitive | boolean | null | default null |
data.request.lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | default null |
data.request.lifestyle.hasPets | boolean | null | default null |
data.request.lifestyle.petType | string | null | at most 60 characters, default null |
data.request.lifestyle.renovationTolerance | "none" | "minor" | "major" | null | default null |
data.request.lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | default null |
data.request.lifestyle.neighborhoodVibe | string | null | at most 200 characters, default null |
data.request.lifestyle.weekendLifestyle | string | null | at most 200 characters, default null |
data.request.neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | at most 6 items, default [] |
data.request.vibe | object | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
data.request.vibe.tags | string[] | at most 12 items, default [] |
data.request.vibe.urbanToQuiet | integer | 0 to 100, default 50 |
data.request.vibe.moveInToProject | integer | 0 to 100, default 50 |
data.request.tasteReactions | object[] | at most 23 items, default [] |
data.request.tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | |
data.request.tasteReactions[].reaction | "love" | "pass" | |
data.request.inspirations | object[], optional | 1 to 4 items |
data.request.inspirations[].listingKey | string, optional | 1 to 100 characters |
data.request.inspirations[].address | string, optional | 1 to 200 characters |
data.request.inspirations[].price | number, optional | 0 to 100000000 |
data.request.inspirations[].beds | integer, optional | 0 to 20 |
data.request.inspirations[].baths | number, optional | 0 to 20 |
data.request.inspirations[].sqft | number, optional | 0 to 100000 |
data.request.inspirations[].description | string, optional | 1 to 300 characters |
data.request.inspirations[].styleSignals | string[], optional | at most 10 items |
data.request.inspirationImportance | "nice" | "must", optional | |
data.request.callbackUrl | string, optional | 1 to 2000 characters |
data.request.includeComingSoon | boolean | default true |
data.request.onMarketSince | string (date) | null | default null |
data.request.options | object | default {"shortlist":4,"grade":25,"photos":8} |
data.request.options.shortlist | integer | 1 to 12, default 4 |
data.request.options.grade | integer | 1 to 40, default 25 |
data.request.options.photos | integer | 0 to 8, default 8 |
data.createdAt | string (date-time) | |
data.updatedAt | string (date-time) | |
data.latestExecution | object | null | The newest run, or null when the search was saved and never run. |
data.latestExecution.id | string (uuid) | The run's id. |
data.latestExecution.searchId | string (uuid) | |
data.latestExecution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.latestExecution.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.latestExecution.stepLabel | string | null | That play in words for a person. |
data.latestExecution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.latestExecution.progress | object | |
data.latestExecution.progress.done | integer | Plays finished. |
data.latestExecution.progress.total | integer | Plays in a run. |
data.latestExecution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.latestExecution.createdAt | string (date-time) | |
data.latestExecution.startedAt | string (date-time) | null | |
data.latestExecution.finishedAt | string (date-time) | null | |
data.latestExecution.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.latestExecution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.latestExecution.links.self | string | |
data.latestExecution.links.search | string | |
data.latestExecution.links.cancel | string | |
data.links | object | |
data.links.self | string | |
data.links.run | string | |
data.links.executions | string |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search in your workspace. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Save a search
/api/v1/search/{searchId}Saves a request at an id you choose, without running it. 201 when the id is new, 200 when it replaced one of yours. Choosing the id makes a retried save land once.
Replacing a search keeps its runs. Send If-Match with the ETag you last read to be sure you are not overwriting someone else's change; a stale revision is 412 and nothing is written.
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. |
If-Match | Header | string | Optional | The ETag of the version you read, such as "3". If the search has changed since, nothing is written and the answer is 412. |
Request body
The whole request, as for starting a search.
Fields (87)
| Field | Type | Required | Description |
|---|---|---|---|
version | 1 | Optional | default 1 |
clientId | string (uuid) | null | Optional | default null |
label | string | null | Optional | 1 to 120 characters, default null |
listingType | "buy" | "rent" | Optional | default "buy" |
location | object | Required | |
location.label | string | Required | 1 to 120 characters |
location.center | object | Optional | |
location.center.lat | number | Required | -90 to 90 |
location.center.lng | number | Required | -180 to 180 |
price | object | Required | |
price.min | number | Optional | 0 to 100000000 |
price.max | number | Required | 0 to 100000000 |
price.budget | number | Optional | 0 to 100000000 |
beds | object | Required | |
beds.min | integer | Required | 0 to 20 |
beds.target | integer | Optional | 0 to 20 |
baths | object | Required | |
baths.min | number | Required | 0 to 20 |
baths.target | number | Optional | 0 to 20 |
sqft | object | Optional | |
sqft.min | number | Optional | 0 to 100000 |
sqft.max | number | Optional | 0 to 100000 |
propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | Optional | at most 6 items, default [] |
commutes | object[] | Optional | at most 3 items, default [] |
commutes[].label | string | Required | 1 to 80 characters |
commutes[].lat | number | Optional | -90 to 90 |
commutes[].lng | number | Optional | -180 to 180 |
commutes[].maxMinutes | integer | Required | 0 to 120 |
commutes[].anyOf | string | Optional | 1 to 80 characters |
pins | object[] | Optional | at most 4 items |
pins[].id | string | Required | 1 to 64 characters |
pins[].lat | number | Required | -90 to 90 |
pins[].lng | number | Required | -180 to 180 |
areas | object[] | Optional | at most 10 items, default [] |
areas[].name | string | Required | 1 to 80 characters |
areas[].lat | number | Required | -90 to 90 |
areas[].lng | number | Required | -180 to 180 |
areas[].weight | integer | Optional | 1 to 10, default 5 |
areas[].kind | "city" | "neighborhood" | Optional | |
areas[].radiusMiles | number | Optional | 0.25 to 25 |
mustHaves | string[] | Optional | at most 20 items, default [] |
niceToHaves | string[] | Optional | at most 20 items, default [] |
dealBreakers | string[] | Optional | at most 20 items, default [] |
idealHome | string | null | Optional | at most 4000 characters, default null |
idealHomeImportance | "nice" | "must" | Optional | |
dislikes | string | null | Optional | at most 2000 characters, default null |
movingReason | string | null | Optional | at most 500 characters, default null |
lifestyle | object | Optional | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
lifestyle.household | string | null | Optional | at most 120 characters, default null |
lifestyle.hasKids | boolean | null | Optional | default null |
lifestyle.kidsAges | string | null | Optional | at most 60 characters, default null |
lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | Optional | default null |
lifestyle.workFromHome | boolean | null | Optional | default null |
lifestyle.wfhDaysPerWeek | number | null | Optional | 0 to 7, default null |
lifestyle.noiseSensitive | boolean | null | Optional | default null |
lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | Optional | default null |
lifestyle.hasPets | boolean | null | Optional | default null |
lifestyle.petType | string | null | Optional | at most 60 characters, default null |
lifestyle.renovationTolerance | "none" | "minor" | "major" | null | Optional | default null |
lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | Optional | default null |
lifestyle.neighborhoodVibe | string | null | Optional | at most 200 characters, default null |
lifestyle.weekendLifestyle | string | null | Optional | at most 200 characters, default null |
neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | Optional | at most 6 items, default [] |
vibe | object | Optional | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
vibe.tags | string[] | Optional | at most 12 items, default [] |
vibe.urbanToQuiet | integer | Optional | 0 to 100, default 50 |
vibe.moveInToProject | integer | Optional | 0 to 100, default 50 |
tasteReactions | object[] | Optional | at most 23 items, default [] |
tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | Required | |
tasteReactions[].reaction | "love" | "pass" | Required | |
inspirations | object[] | Optional | 1 to 4 items |
inspirations[].listingKey | string | Optional | 1 to 100 characters |
inspirations[].address | string | Optional | 1 to 200 characters |
inspirations[].price | number | Optional | 0 to 100000000 |
inspirations[].beds | integer | Optional | 0 to 20 |
inspirations[].baths | number | Optional | 0 to 20 |
inspirations[].sqft | number | Optional | 0 to 100000 |
inspirations[].description | string | Optional | 1 to 300 characters |
inspirations[].styleSignals | string[] | Optional | at most 10 items |
inspirationImportance | "nice" | "must" | Optional | |
callbackUrl | string | Optional | 1 to 2000 characters |
includeComingSoon | boolean | Optional | default true |
onMarketSince | string (date) | null | Optional | default null |
options | object | Optional | default {"shortlist":4,"grade":25,"photos":8} |
options.shortlist | integer | Optional | 1 to 12, default 4 |
options.grade | integer | Optional | 1 to 40, default 25 |
options.photos | integer | Optional | 0 to 8, default 8 |
{
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"options": {
"shortlist": 4
}
}Examples
curl -X PUT "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"options": {
"shortlist": 4
}
}'Responses
A new search was saved.
HeadersETagLocation
{
"data": {
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"label": "Okafors, East Nashville",
"clientId": null,
"revision": 1,
"request": {
"version": 1,
"clientId": null,
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"areas": [],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"dislikes": null,
"movingReason": null,
"lifestyle": {
"household": null,
"hasKids": null,
"kidsAges": null,
"schoolPriority": null,
"workFromHome": null,
"wfhDaysPerWeek": null,
"noiseSensitive": null,
"yardImportance": null,
"hasPets": null,
"petType": null,
"renovationTolerance": null,
"hoaPreference": null,
"neighborhoodVibe": null,
"weekendLifestyle": null
},
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"vibe": {
"tags": [],
"urbanToQuiet": 50,
"moveInToProject": 50
},
"tasteReactions": [],
"includeComingSoon": true,
"onMarketSince": null,
"options": {
"shortlist": 4,
"grade": 25,
"photos": 8
}
},
"createdAt": "2026-10-02T14:03:11.402Z",
"updatedAt": "2026-10-02T14:03:11.402Z",
"latestExecution": null,
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"run": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"executions": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions"
}
}
}Fields (118)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.label | string | null | |
data.clientId | string (uuid) | null | |
data.revision | integer | Counts up on every save. The same number is the ETag.at least 1 |
data.request | object | The request as saved, every default filled in. |
data.request.version | 1 | default 1 |
data.request.clientId | string (uuid) | null | default null |
data.request.label | string | null | 1 to 120 characters, default null |
data.request.listingType | "buy" | "rent" | default "buy" |
data.request.location | object | |
data.request.location.label | string | 1 to 120 characters |
data.request.location.center | object, optional | |
data.request.location.center.lat | number | -90 to 90 |
data.request.location.center.lng | number | -180 to 180 |
data.request.price | object | |
data.request.price.min | number, optional | 0 to 100000000 |
data.request.price.max | number | 0 to 100000000 |
data.request.price.budget | number, optional | 0 to 100000000 |
data.request.beds | object | |
data.request.beds.min | integer | 0 to 20 |
data.request.beds.target | integer, optional | 0 to 20 |
data.request.baths | object | |
data.request.baths.min | number | 0 to 20 |
data.request.baths.target | number, optional | 0 to 20 |
data.request.sqft | object, optional | |
data.request.sqft.min | number, optional | 0 to 100000 |
data.request.sqft.max | number, optional | 0 to 100000 |
data.request.propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | at most 6 items, default [] |
data.request.commutes | object[] | at most 3 items, default [] |
data.request.commutes[].label | string | 1 to 80 characters |
data.request.commutes[].lat | number, optional | -90 to 90 |
data.request.commutes[].lng | number, optional | -180 to 180 |
data.request.commutes[].maxMinutes | integer | 0 to 120 |
data.request.commutes[].anyOf | string, optional | 1 to 80 characters |
data.request.pins | object[], optional | at most 4 items |
data.request.pins[].id | string | 1 to 64 characters |
data.request.pins[].lat | number | -90 to 90 |
data.request.pins[].lng | number | -180 to 180 |
data.request.areas | object[] | at most 10 items, default [] |
data.request.areas[].name | string | 1 to 80 characters |
data.request.areas[].lat | number | -90 to 90 |
data.request.areas[].lng | number | -180 to 180 |
data.request.areas[].weight | integer | 1 to 10, default 5 |
data.request.areas[].kind | "city" | "neighborhood", optional | |
data.request.areas[].radiusMiles | number, optional | 0.25 to 25 |
data.request.mustHaves | string[] | at most 20 items, default [] |
data.request.niceToHaves | string[] | at most 20 items, default [] |
data.request.dealBreakers | string[] | at most 20 items, default [] |
data.request.idealHome | string | null | at most 4000 characters, default null |
data.request.idealHomeImportance | "nice" | "must", optional | |
data.request.dislikes | string | null | at most 2000 characters, default null |
data.request.movingReason | string | null | at most 500 characters, default null |
data.request.lifestyle | object | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
data.request.lifestyle.household | string | null | at most 120 characters, default null |
data.request.lifestyle.hasKids | boolean | null | default null |
data.request.lifestyle.kidsAges | string | null | at most 60 characters, default null |
data.request.lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | default null |
data.request.lifestyle.workFromHome | boolean | null | default null |
data.request.lifestyle.wfhDaysPerWeek | number | null | 0 to 7, default null |
data.request.lifestyle.noiseSensitive | boolean | null | default null |
data.request.lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | default null |
data.request.lifestyle.hasPets | boolean | null | default null |
data.request.lifestyle.petType | string | null | at most 60 characters, default null |
data.request.lifestyle.renovationTolerance | "none" | "minor" | "major" | null | default null |
data.request.lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | default null |
data.request.lifestyle.neighborhoodVibe | string | null | at most 200 characters, default null |
data.request.lifestyle.weekendLifestyle | string | null | at most 200 characters, default null |
data.request.neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | at most 6 items, default [] |
data.request.vibe | object | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
data.request.vibe.tags | string[] | at most 12 items, default [] |
data.request.vibe.urbanToQuiet | integer | 0 to 100, default 50 |
data.request.vibe.moveInToProject | integer | 0 to 100, default 50 |
data.request.tasteReactions | object[] | at most 23 items, default [] |
data.request.tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | |
data.request.tasteReactions[].reaction | "love" | "pass" | |
data.request.inspirations | object[], optional | 1 to 4 items |
data.request.inspirations[].listingKey | string, optional | 1 to 100 characters |
data.request.inspirations[].address | string, optional | 1 to 200 characters |
data.request.inspirations[].price | number, optional | 0 to 100000000 |
data.request.inspirations[].beds | integer, optional | 0 to 20 |
data.request.inspirations[].baths | number, optional | 0 to 20 |
data.request.inspirations[].sqft | number, optional | 0 to 100000 |
data.request.inspirations[].description | string, optional | 1 to 300 characters |
data.request.inspirations[].styleSignals | string[], optional | at most 10 items |
data.request.inspirationImportance | "nice" | "must", optional | |
data.request.callbackUrl | string, optional | 1 to 2000 characters |
data.request.includeComingSoon | boolean | default true |
data.request.onMarketSince | string (date) | null | default null |
data.request.options | object | default {"shortlist":4,"grade":25,"photos":8} |
data.request.options.shortlist | integer | 1 to 12, default 4 |
data.request.options.grade | integer | 1 to 40, default 25 |
data.request.options.photos | integer | 0 to 8, default 8 |
data.createdAt | string (date-time) | |
data.updatedAt | string (date-time) | |
data.latestExecution | object | null | The newest run, or null when the search was saved and never run. |
data.latestExecution.id | string (uuid) | The run's id. |
data.latestExecution.searchId | string (uuid) | |
data.latestExecution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.latestExecution.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.latestExecution.stepLabel | string | null | That play in words for a person. |
data.latestExecution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.latestExecution.progress | object | |
data.latestExecution.progress.done | integer | Plays finished. |
data.latestExecution.progress.total | integer | Plays in a run. |
data.latestExecution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.latestExecution.createdAt | string (date-time) | |
data.latestExecution.startedAt | string (date-time) | null | |
data.latestExecution.finishedAt | string (date-time) | null | |
data.latestExecution.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.latestExecution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.latestExecution.links.self | string | |
data.latestExecution.links.search | string | |
data.latestExecution.links.cancel | string | |
data.links | object | |
data.links.self | string | |
data.links.run | string | |
data.links.executions | string |
An existing search was replaced.
HeadersETagLocation
{
"data": {
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"label": "Okafors, East Nashville",
"clientId": null,
"revision": 2,
"request": {
"version": 1,
"clientId": null,
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"areas": [],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"dislikes": null,
"movingReason": null,
"lifestyle": {
"household": null,
"hasKids": null,
"kidsAges": null,
"schoolPriority": null,
"workFromHome": null,
"wfhDaysPerWeek": null,
"noiseSensitive": null,
"yardImportance": null,
"hasPets": null,
"petType": null,
"renovationTolerance": null,
"hoaPreference": null,
"neighborhoodVibe": null,
"weekendLifestyle": null
},
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"vibe": {
"tags": [],
"urbanToQuiet": 50,
"moveInToProject": 50
},
"tasteReactions": [],
"includeComingSoon": true,
"onMarketSince": null,
"options": {
"shortlist": 4,
"grade": 25,
"photos": 8
}
},
"createdAt": "2026-10-02T14:03:11.402Z",
"updatedAt": "2026-10-02T14:03:11.402Z",
"latestExecution": {
"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"
}
},
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"run": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"executions": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions"
}
}
}Fields (118)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.label | string | null | |
data.clientId | string (uuid) | null | |
data.revision | integer | Counts up on every save. The same number is the ETag.at least 1 |
data.request | object | The request as saved, every default filled in. |
data.request.version | 1 | default 1 |
data.request.clientId | string (uuid) | null | default null |
data.request.label | string | null | 1 to 120 characters, default null |
data.request.listingType | "buy" | "rent" | default "buy" |
data.request.location | object | |
data.request.location.label | string | 1 to 120 characters |
data.request.location.center | object, optional | |
data.request.location.center.lat | number | -90 to 90 |
data.request.location.center.lng | number | -180 to 180 |
data.request.price | object | |
data.request.price.min | number, optional | 0 to 100000000 |
data.request.price.max | number | 0 to 100000000 |
data.request.price.budget | number, optional | 0 to 100000000 |
data.request.beds | object | |
data.request.beds.min | integer | 0 to 20 |
data.request.beds.target | integer, optional | 0 to 20 |
data.request.baths | object | |
data.request.baths.min | number | 0 to 20 |
data.request.baths.target | number, optional | 0 to 20 |
data.request.sqft | object, optional | |
data.request.sqft.min | number, optional | 0 to 100000 |
data.request.sqft.max | number, optional | 0 to 100000 |
data.request.propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | at most 6 items, default [] |
data.request.commutes | object[] | at most 3 items, default [] |
data.request.commutes[].label | string | 1 to 80 characters |
data.request.commutes[].lat | number, optional | -90 to 90 |
data.request.commutes[].lng | number, optional | -180 to 180 |
data.request.commutes[].maxMinutes | integer | 0 to 120 |
data.request.commutes[].anyOf | string, optional | 1 to 80 characters |
data.request.pins | object[], optional | at most 4 items |
data.request.pins[].id | string | 1 to 64 characters |
data.request.pins[].lat | number | -90 to 90 |
data.request.pins[].lng | number | -180 to 180 |
data.request.areas | object[] | at most 10 items, default [] |
data.request.areas[].name | string | 1 to 80 characters |
data.request.areas[].lat | number | -90 to 90 |
data.request.areas[].lng | number | -180 to 180 |
data.request.areas[].weight | integer | 1 to 10, default 5 |
data.request.areas[].kind | "city" | "neighborhood", optional | |
data.request.areas[].radiusMiles | number, optional | 0.25 to 25 |
data.request.mustHaves | string[] | at most 20 items, default [] |
data.request.niceToHaves | string[] | at most 20 items, default [] |
data.request.dealBreakers | string[] | at most 20 items, default [] |
data.request.idealHome | string | null | at most 4000 characters, default null |
data.request.idealHomeImportance | "nice" | "must", optional | |
data.request.dislikes | string | null | at most 2000 characters, default null |
data.request.movingReason | string | null | at most 500 characters, default null |
data.request.lifestyle | object | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
data.request.lifestyle.household | string | null | at most 120 characters, default null |
data.request.lifestyle.hasKids | boolean | null | default null |
data.request.lifestyle.kidsAges | string | null | at most 60 characters, default null |
data.request.lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | default null |
data.request.lifestyle.workFromHome | boolean | null | default null |
data.request.lifestyle.wfhDaysPerWeek | number | null | 0 to 7, default null |
data.request.lifestyle.noiseSensitive | boolean | null | default null |
data.request.lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | default null |
data.request.lifestyle.hasPets | boolean | null | default null |
data.request.lifestyle.petType | string | null | at most 60 characters, default null |
data.request.lifestyle.renovationTolerance | "none" | "minor" | "major" | null | default null |
data.request.lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | default null |
data.request.lifestyle.neighborhoodVibe | string | null | at most 200 characters, default null |
data.request.lifestyle.weekendLifestyle | string | null | at most 200 characters, default null |
data.request.neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | at most 6 items, default [] |
data.request.vibe | object | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
data.request.vibe.tags | string[] | at most 12 items, default [] |
data.request.vibe.urbanToQuiet | integer | 0 to 100, default 50 |
data.request.vibe.moveInToProject | integer | 0 to 100, default 50 |
data.request.tasteReactions | object[] | at most 23 items, default [] |
data.request.tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | |
data.request.tasteReactions[].reaction | "love" | "pass" | |
data.request.inspirations | object[], optional | 1 to 4 items |
data.request.inspirations[].listingKey | string, optional | 1 to 100 characters |
data.request.inspirations[].address | string, optional | 1 to 200 characters |
data.request.inspirations[].price | number, optional | 0 to 100000000 |
data.request.inspirations[].beds | integer, optional | 0 to 20 |
data.request.inspirations[].baths | number, optional | 0 to 20 |
data.request.inspirations[].sqft | number, optional | 0 to 100000 |
data.request.inspirations[].description | string, optional | 1 to 300 characters |
data.request.inspirations[].styleSignals | string[], optional | at most 10 items |
data.request.inspirationImportance | "nice" | "must", optional | |
data.request.callbackUrl | string, optional | 1 to 2000 characters |
data.request.includeComingSoon | boolean | default true |
data.request.onMarketSince | string (date) | null | default null |
data.request.options | object | default {"shortlist":4,"grade":25,"photos":8} |
data.request.options.shortlist | integer | 1 to 12, default 4 |
data.request.options.grade | integer | 1 to 40, default 25 |
data.request.options.photos | integer | 0 to 8, default 8 |
data.createdAt | string (date-time) | |
data.updatedAt | string (date-time) | |
data.latestExecution | object | null | The newest run, or null when the search was saved and never run. |
data.latestExecution.id | string (uuid) | The run's id. |
data.latestExecution.searchId | string (uuid) | |
data.latestExecution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.latestExecution.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.latestExecution.stepLabel | string | null | That play in words for a person. |
data.latestExecution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.latestExecution.progress | object | |
data.latestExecution.progress.done | integer | Plays finished. |
data.latestExecution.progress.total | integer | Plays in a run. |
data.latestExecution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.latestExecution.createdAt | string (date-time) | |
data.latestExecution.startedAt | string (date-time) | null | |
data.latestExecution.finishedAt | string (date-time) | null | |
data.latestExecution.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.latestExecution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.latestExecution.links.self | string | |
data.latestExecution.links.search | string | |
data.latestExecution.links.cancel | string | |
data.links | object | |
data.links.self | string | |
data.links.run | string | |
data.links.executions | string |
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid | The request failed validation; issues names each field. |
| 400 | invalid-json | The body is empty or not JSON. |
| 400 | invalid-if-match | The If-Match is not a revision. |
| 409 | id-unavailable | The id belongs to something that is not yours. |
| 412 | revision-mismatch | The search changed since the revision in If-Match. |
| 413 | too-large | The body is over 64 KiB. |
| 422 | unknown-client | clientId is not a client in the workspace. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Run a saved search
/api/v1/search/{searchId}Queues another run of a saved search and answers 202, exactly as starting one does. Use it to re-run a search as the market moves.
The body is optional. overrides replaces top-level keys of the saved request for this run only ({ "overrides": { "price": { "max": 700000 } } }), and the merged request is validated again, so an override can never produce a request the API would refuse. The saved search itself is not changed.
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. |
Idempotency-Key | Header | string | Optional | A value of your own for this attempt. The same key with the same request replays the first answer (Idempotent-Replayed: true) and starts nothing new; the same key with a different request is 409. A key is remembered for as long as its run exists. |
Request body
Optional. Top-level keys of the request to replace for this run. The body is optional.
Fields (1)
| Field | Type | Required | Description |
|---|---|---|---|
overrides | object | Optional | default {} |
{
"overrides": {
"price": {
"min": 450000,
"max": 700000
}
}
}Examples
curl -X POST "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Idempotency-Key: okafor-east-nashville-1" \
-H "Content-Type: application/json" \
-d '{
"overrides": {
"price": {
"min": 450000,
"max": 700000
}
}
}'Responses
A run was queued.
HeadersLocationRetry-AfterIdempotent-Replayed
{
"data": {
"search": {
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"label": "Okafors, East Nashville",
"clientId": null,
"revision": 1,
"request": {
"version": 1,
"clientId": null,
"label": "Okafors, East Nashville",
"listingType": "buy",
"location": {
"label": "Nashville, TN",
"center": {
"lat": 36.1627,
"lng": -86.7816
}
},
"price": {
"min": 450000,
"max": 750000
},
"beds": {
"min": 3
},
"baths": {
"min": 2
},
"sqft": {
"min": 1800
},
"propertyTypes": [
"single-family"
],
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"lat": 36.1421,
"lng": -86.8016,
"maxMinutes": 25
}
],
"areas": [],
"mustHaves": [
"Fenced yard",
"Walkable to coffee"
],
"niceToHaves": [
"Home office"
],
"dealBreakers": [
"Busy road"
],
"idealHome": "A renovated bungalow with big windows and a porch, close to the park.",
"dislikes": null,
"movingReason": null,
"lifestyle": {
"household": null,
"hasKids": null,
"kidsAges": null,
"schoolPriority": null,
"workFromHome": null,
"wfhDaysPerWeek": null,
"noiseSensitive": null,
"yardImportance": null,
"hasPets": null,
"petType": null,
"renovationTolerance": null,
"hoaPreference": null,
"neighborhoodVibe": null,
"weekendLifestyle": null
},
"neighbourhood": [
"great-schools",
"walkable-lively"
],
"vibe": {
"tags": [],
"urbanToQuiet": 50,
"moveInToProject": 50
},
"tasteReactions": [],
"includeComingSoon": true,
"onMarketSince": null,
"options": {
"shortlist": 4,
"grade": 25,
"photos": 8
}
},
"createdAt": "2026-10-02T14:03:11.402Z",
"updatedAt": "2026-10-02T14:03:11.402Z",
"latestExecution": {
"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"
}
},
"links": {
"self": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"run": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"executions": "/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions"
}
},
"execution": {
"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"
}
}
}
}Fields (138)
| Field | Type | Description |
|---|---|---|
data | object | |
data.search | object | |
data.search.id | string (uuid) | |
data.search.label | string | null | |
data.search.clientId | string (uuid) | null | |
data.search.revision | integer | Counts up on every save. The same number is the ETag.at least 1 |
data.search.request | object | The request as saved, every default filled in. |
data.search.request.version | 1 | default 1 |
data.search.request.clientId | string (uuid) | null | default null |
data.search.request.label | string | null | 1 to 120 characters, default null |
data.search.request.listingType | "buy" | "rent" | default "buy" |
data.search.request.location | object | |
data.search.request.location.label | string | 1 to 120 characters |
data.search.request.location.center | object, optional | |
data.search.request.location.center.lat | number | -90 to 90 |
data.search.request.location.center.lng | number | -180 to 180 |
data.search.request.price | object | |
data.search.request.price.min | number, optional | 0 to 100000000 |
data.search.request.price.max | number | 0 to 100000000 |
data.search.request.price.budget | number, optional | 0 to 100000000 |
data.search.request.beds | object | |
data.search.request.beds.min | integer | 0 to 20 |
data.search.request.beds.target | integer, optional | 0 to 20 |
data.search.request.baths | object | |
data.search.request.baths.min | number | 0 to 20 |
data.search.request.baths.target | number, optional | 0 to 20 |
data.search.request.sqft | object, optional | |
data.search.request.sqft.min | number, optional | 0 to 100000 |
data.search.request.sqft.max | number, optional | 0 to 100000 |
data.search.request.propertyTypes | ("single-family" | "condo" | "townhome" | "multi-family" | "manufactured" | "land")[] | at most 6 items, default [] |
data.search.request.commutes | object[] | at most 3 items, default [] |
data.search.request.commutes[].label | string | 1 to 80 characters |
data.search.request.commutes[].lat | number, optional | -90 to 90 |
data.search.request.commutes[].lng | number, optional | -180 to 180 |
data.search.request.commutes[].maxMinutes | integer | 0 to 120 |
data.search.request.commutes[].anyOf | string, optional | 1 to 80 characters |
data.search.request.pins | object[], optional | at most 4 items |
data.search.request.pins[].id | string | 1 to 64 characters |
data.search.request.pins[].lat | number | -90 to 90 |
data.search.request.pins[].lng | number | -180 to 180 |
data.search.request.areas | object[] | at most 10 items, default [] |
data.search.request.areas[].name | string | 1 to 80 characters |
data.search.request.areas[].lat | number | -90 to 90 |
data.search.request.areas[].lng | number | -180 to 180 |
data.search.request.areas[].weight | integer | 1 to 10, default 5 |
data.search.request.areas[].kind | "city" | "neighborhood", optional | |
data.search.request.areas[].radiusMiles | number, optional | 0.25 to 25 |
data.search.request.mustHaves | string[] | at most 20 items, default [] |
data.search.request.niceToHaves | string[] | at most 20 items, default [] |
data.search.request.dealBreakers | string[] | at most 20 items, default [] |
data.search.request.idealHome | string | null | at most 4000 characters, default null |
data.search.request.idealHomeImportance | "nice" | "must", optional | |
data.search.request.dislikes | string | null | at most 2000 characters, default null |
data.search.request.movingReason | string | null | at most 500 characters, default null |
data.search.request.lifestyle | object | default {"household":null,"hasKids":null,"kidsAges":null,"schoolPriority":null,"workFromHome":null,"wfhDaysPerWeek":null,"noiseSensitive":null,"yardImportance":null,"hasPets":null,"petType":null,"renovationTolerance":null,"hoaPreference":null,"neighborhoodVibe":null,"weekendLifestyle":null} |
data.search.request.lifestyle.household | string | null | at most 120 characters, default null |
data.search.request.lifestyle.hasKids | boolean | null | default null |
data.search.request.lifestyle.kidsAges | string | null | at most 60 characters, default null |
data.search.request.lifestyle.schoolPriority | "critical" | "important" | "nice" | "none" | null | default null |
data.search.request.lifestyle.workFromHome | boolean | null | default null |
data.search.request.lifestyle.wfhDaysPerWeek | number | null | 0 to 7, default null |
data.search.request.lifestyle.noiseSensitive | boolean | null | default null |
data.search.request.lifestyle.yardImportance | "critical" | "important" | "nice" | "none" | null | default null |
data.search.request.lifestyle.hasPets | boolean | null | default null |
data.search.request.lifestyle.petType | string | null | at most 60 characters, default null |
data.search.request.lifestyle.renovationTolerance | "none" | "minor" | "major" | null | default null |
data.search.request.lifestyle.hoaPreference | "avoid" | "ok" | "prefer" | null | default null |
data.search.request.lifestyle.neighborhoodVibe | string | null | at most 200 characters, default null |
data.search.request.lifestyle.weekendLifestyle | string | null | at most 200 characters, default null |
data.search.request.neighbourhood | ("safe-low-crime" | "great-schools" | "walkable-lively" | "near-parks" | "quiet-residential" | "up-and-coming")[] | at most 6 items, default [] |
data.search.request.vibe | object | default {"tags":[],"urbanToQuiet":50,"moveInToProject":50} |
data.search.request.vibe.tags | string[] | at most 12 items, default [] |
data.search.request.vibe.urbanToQuiet | integer | 0 to 100, default 50 |
data.search.request.vibe.moveInToProject | integer | 0 to 100, default 50 |
data.search.request.tasteReactions | object[] | at most 23 items, default [] |
data.search.request.tasteReactions[].cardId | "views-city" | "views-mountain" | "views-water" | "views-treetops" | "light-floor-ceiling" | "light-bright-airy" | "light-cozy" | "kitchen-gourmet" | "kitchen-family" | "kitchen-minimal" | "outdoor-pool" | "outdoor-garden" | "outdoor-balcony" | "outdoor-minimal" | "living-open" | "living-rooms" | "living-loft" | "office-dedicated" | "office-flex" | "office-none" | "cond-move-in" | "cond-updates" | "cond-project" | |
data.search.request.tasteReactions[].reaction | "love" | "pass" | |
data.search.request.inspirations | object[], optional | 1 to 4 items |
data.search.request.inspirations[].listingKey | string, optional | 1 to 100 characters |
data.search.request.inspirations[].address | string, optional | 1 to 200 characters |
data.search.request.inspirations[].price | number, optional | 0 to 100000000 |
data.search.request.inspirations[].beds | integer, optional | 0 to 20 |
data.search.request.inspirations[].baths | number, optional | 0 to 20 |
data.search.request.inspirations[].sqft | number, optional | 0 to 100000 |
data.search.request.inspirations[].description | string, optional | 1 to 300 characters |
data.search.request.inspirations[].styleSignals | string[], optional | at most 10 items |
data.search.request.inspirationImportance | "nice" | "must", optional | |
data.search.request.callbackUrl | string, optional | 1 to 2000 characters |
data.search.request.includeComingSoon | boolean | default true |
data.search.request.onMarketSince | string (date) | null | default null |
data.search.request.options | object | default {"shortlist":4,"grade":25,"photos":8} |
data.search.request.options.shortlist | integer | 1 to 12, default 4 |
data.search.request.options.grade | integer | 1 to 40, default 25 |
data.search.request.options.photos | integer | 0 to 8, default 8 |
data.search.createdAt | string (date-time) | |
data.search.updatedAt | string (date-time) | |
data.search.latestExecution | object | null | The newest run, or null when the search was saved and never run. |
data.search.latestExecution.id | string (uuid) | The run's id. |
data.search.latestExecution.searchId | string (uuid) | |
data.search.latestExecution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.search.latestExecution.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.search.latestExecution.stepLabel | string | null | That play in words for a person. |
data.search.latestExecution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.search.latestExecution.progress | object | |
data.search.latestExecution.progress.done | integer | Plays finished. |
data.search.latestExecution.progress.total | integer | Plays in a run. |
data.search.latestExecution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.search.latestExecution.createdAt | string (date-time) | |
data.search.latestExecution.startedAt | string (date-time) | null | |
data.search.latestExecution.finishedAt | string (date-time) | null | |
data.search.latestExecution.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.search.latestExecution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.search.latestExecution.links.self | string | |
data.search.latestExecution.links.search | string | |
data.search.latestExecution.links.cancel | string | |
data.search.links | object | |
data.search.links.self | string | |
data.search.links.run | string | |
data.search.links.executions | string | |
data.execution | object | |
data.execution.id | string (uuid) | The run's id. |
data.execution.searchId | string (uuid) | |
data.execution.status | "queued" | "running" | "succeeded" | "failed" | "canceled" | queued and running are unfinished: keep polling. succeeded, failed and canceled are final. |
data.execution.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.execution.stepLabel | string | null | That play in words for a person. |
data.execution.attempts | integer | How many times a driver has claimed the run. More than one means it resumed after a crash or a deadline. |
data.execution.progress | object | |
data.execution.progress.done | integer | Plays finished. |
data.execution.progress.total | integer | Plays in a run. |
data.execution.progress.percent | integer | How far along, 0 to 100. It moves inside a long play.0 to 100 |
data.execution.createdAt | string (date-time) | |
data.execution.startedAt | string (date-time) | null | |
data.execution.finishedAt | string (date-time) | null | |
data.execution.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.execution.links | object | Where to read this run, its search, and where to POST to cancel it. |
data.execution.links.self | string | |
data.execution.links.search | string | |
data.execution.links.cancel | string |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search in your workspace. |
| 400 | invalid | The request failed validation; issues names each field. |
| 400 | invalid-json | The body is not JSON. |
| 400 | invalid-idempotency-key | The Idempotency-Key is malformed. |
| 402 | out-of-credits | The org has no matches left this month. |
| 402 | person-limit-reached | The person the key acts as has used their own monthly matches. |
| 409 | idempotency-key-reused | The Idempotency-Key was used for a different request. |
| 413 | too-large | The body is over 64 KiB. |
| 422 | unknown-client | clientId is not a client in the workspace. |
| 422 | callback-url-refused | The callbackUrl is plain http to localhost on a deployment that is not development. |
| 422 | callback-needs-key | The run names a callbackUrl but was started without an API key. |
| 422 | no-signing-secret | The run names a callbackUrl and the key has no signing secret. |
| 429 | rate-limited | The hourly cap on starting runs is spent (the answer has no RateLimit header). |
| 429 | too-many-active | 3 runs are already queued or running. |
| 503 | search-unavailable | An outside service the run needs is not configured here. |
| 503 | studio-incomplete | A prompt the match engine runs is incomplete in Livia's AI settings; issues names the step. Nothing was started or spent. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 monthly-cap-reached500 internal
Delete a search
/api/v1/search/{searchId}Deletes a saved search with its runs, their steps and their pools. A run in flight loses its claim and stops at its next heartbeat. What the search spent stays on the usage ledger, so deleting never un-spends the month. This cannot be undone.
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. |
If-Match | Header | string | Optional | The ETag of the version you read, such as "3". If the search has changed since, nothing is written and the answer is 412. |
Examples
curl -X DELETE "https://liviamatch.com/api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
The search is gone.
{
"data": {
"id": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"deleted": true
}
}Fields (3)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.deleted | true |
Errors
| Status | Code | When |
|---|---|---|
| 404 | not-found | No such search in your workspace. |
| 400 | invalid-if-match | The If-Match is not a revision. |
| 412 | revision-mismatch | The search changed since the revision in If-Match; it was kept. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal