Quickstart
Make a key, start a match, wait for it, read the shortlist.
You will make a key, check it works, start a headless search, wait for it, and read the shortlist. Each step has the call in cURL, TypeScript and Python.
Headless vs the app
POST /api/v1/search. That path returns a shortlist on the execution but does not create a run of a search, so nothing appears under Searches or Clients. For the product path (client → search → run → share, visible in the app), use From a client to shared results. The poll contract is the same either way: Runs and polling.1. Make a key
- Sign in and open Settings, API keys.
- Name it for the tool and the job, in lowercase with dashes:
crm-search. - Leave Run matches ticked. That is the one scope this quickstart needs. Choose how long the key lives; three months is a good start.
- Press Make key, and copy the key now. It is shown once.
Put it in your environment, never in code or a URL:
export LIVIA_API_KEY="paste-your-key-here"Treat it like a password
lmp_ (yours) or lmo_ (your organization's), so a secret scanner can recognize one if it leaks.2. Check the key
List your searches. A new account has none, and an empty list with 200 means the key works and may read searches (a key that runs matches may read them too).
curl "https://liviamatch.com/api/v1/search" \
-H "Authorization: Bearer $LIVIA_API_KEY"{ "data": [], "links": { "next": null } }A 401 means the key was not accepted. A 403 with insufficient_scope means it is live but lacks a scope. See Authentication.
3. Start a match
POST /api/v1/search saves the request and queues its first run. It answers 202 at once: the run takes a minute or two and works in the background. Send an Idempotency-Key so a retry after a network error cannot start a second run.
Only location, price.max, beds.min, baths.min and a place to start from (a commute, an area, or location.center) are required. Everything else makes the match better. The full list is in the Searches reference.
curl -X POST "https://liviamatch.com/api/v1/search" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: okafor-east-nashville-1" \
-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
}
}'The answer names the search, the queued run, and where to read the run:
{
"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"
}
}
}
}Location: /api/v1/search/6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60/executions/0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83
Retry-After: 24. Wait for it
GET the Location until status is succeeded, failed or canceled. Wait Retry-After seconds between reads (it is 2), and stop after a few minutes. progress.percent and stepLabel are for showing a person how far along it is.
RUN="https://liviamatch.com/api/v1/search/<searchId>/executions/<executionId>"
while true; do
STATUS=$(curl -s "$RUN" -H "Authorization: Bearer $LIVIA_API_KEY" | jq -r .data.status)
echo "$STATUS"
case "$STATUS" in succeeded|failed|canceled) break;; esac
sleep 2
done{
"data": {
"id": "0d9e7c1a-52b8-4f3a-8e6d-1c7a9b2f4e83",
"searchId": "6f1c2b9e-0a45-4d7e-9a1c-3b2f8d4e5a60",
"status": "running",
"step": "grade",
"stepLabel": "Reading each home's words and photos",
"attempts": 1,
"progress": {
"done": 6,
"total": 9,
"percent": 71
},
"createdAt": "2026-10-02T14:03:12.118Z",
"startedAt": 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"
}
}
}5. Read the shortlist
Once status is succeeded, result is present and never changes again. result.shortlist is the homes that fit, best first. Each has its facts, a blended score from 0 to 100 with its parts in scores, a take in a sentence, and its pros and cons.
if (run.status !== 'succeeded') throw new Error(`Run ${run.status}: ${run.error?.code}`)
for (const home of run.result.shortlist) {
console.log(`${home.rank}. ${home.address}, ${home.city} $${home.price} (score ${home.score})`)
console.log(` ${home.take}`)
}
// Required wherever the homes are shown.
for (const credit of run.result.credits) console.log(credit.text)
for (const note of run.result.notes) console.warn(`stand-in: ${note}`){
"rank": 1,
"listingKey": "NSH-2283104",
"address": "1204 Boscobel St",
"city": "Nashville",
"state": "TN",
"postalCode": "37206",
"neighbourhood": "East Nashville",
"price": 689000,
"beds": 3,
"baths": 2.5,
"sqft": 2140,
"yearBuilt": 1926,
"propertyType": "Residential",
"photo": "https://photos.example.com/NSH-2283104/hero.jpg",
"score": 91.4,
"scores": {
"math": 88.2,
"text": 93,
"photos": 92.5,
"neighbourhood": 90
},
"take": "A renovated 1926 bungalow with the fenced yard and the porch they asked for, 14 minutes from the hospital.",
"pros": [
"Fenced backyard",
"Walkable to two coffee shops",
"Dedicated home office"
],
"cons": [
"One bathroom is down a hallway from the primary"
],
"highlights": [
"Original heart-pine floors",
"Deep front porch"
],
"concerns": [],
"lookAndFeel": "Warm, bright, restored rather than flipped.",
"commutes": [
{
"label": "Vanderbilt University Medical Center",
"minutes": 14,
"estimated": false
}
],
"signals": {
"school": 78,
"safety": 71
},
"breakdown": {
"price": 24.1,
"sqft": 18.5,
"beds": 9.2,
"baths": 9.6,
"travel": {
"location_1": 26.8
},
"bonuses": 0,
"total": 88.2
},
"blendWeights": {
"math": 0.4,
"text": 0.3,
"photos": 0.2,
"neighbourhood": 0.1
},
"officeName": "Hearth & Key Realty",
"unconfirmed": [
"two-car garage"
],
"confirmed": [
"fenced yard"
],
"keyPhotos": [
{
"url": "https://photos.example.com/NSH-2283104/kitchen.jpg",
"label": "Kitchen"
}
],
"gallery": [
"https://photos.example.com/NSH-2283104/hero.jpg",
"https://photos.example.com/NSH-2283104/kitchen.jpg"
]
}Show what the result asks you to show
result.credits is attribution a provider's terms require wherever the result is displayed, and officeName is the listing broker, which MLS rules require beside a home. result.notes lists every stand-in the run used, so a result is never passed off as live when part of it was not. An empty notes means everything was live.Where next
- Re-run the same search as the market moves:
POST /api/v1/search/{searchId}. - See why a home that is not on the shortlist missed it: the pool.
- Handle the failures a real integration meets: Errors and Rate limits.