Title insurance and conveyancing in the United States and Canada processes an enormous volume of property closings every year. Each requires verifying details, confirming addresses, cross-referencing assessments, and validating that the legal description matches reality.
The cost of errors is significant: A single mistake in property identification can lead to claims costing tens of thousands to resolve. Yet much of this work still depends on manual lookups across multiple systems.
Property verification APIs cut errors and improve processing speed by replacing manual lookups with a single call.
The verification challenge
Every title closing needs answers to:
- Does this property exist? Is the address valid and standardized?
- Is the description accurate? Do the legal description and physical characteristics match?
- What's the property worth? Is the closing value reasonable?
- Are there red flags? Assessment anomalies, unusual characteristics, potential issues?
Traditionally that meant:
- Manual lookups in assessment databases
- Cross-referencing multiple address formats
- Comparing client-provided details against official records
- Physical verification for unusual cases
Each manual step introduces delay and error.
API-powered property verification
Modern title operations automate verification by checking details against comprehensive databases. A verification workflow chains two calls: first /search to resolve the client-supplied address to a property_id, then /properties to pull the full record for comparison. The /properties call looks something like this:
const houski_data = async (): Promise<PropertiesResponse> => {
// You must copy the PropertiesResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/properties');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('property_id_eq', 'bd9c6fb24c31c772');
url.searchParams.set('select', 'address,city,province_abbreviation,postal_code,property_type,construction_year,interior_sq_m,land_area_sq_m,assessment_value,assessment_year,estimate_sale_price,latitude,longitude');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: PropertiesResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.68,
"data": [
{
"address": "302 610 17 Avenue SW",
"assessment_value": 301500,
"assessment_year": 2026,
"city": "Calgary",
"construction_year": 1979,
"estimate_sale_price": 294333,
"interior_sq_m": 92.438484,
"land_area_sq_m": 0.0,
"latitude": 51.038193,
"longitude": -114.0751,
"postal_code": "T2S0B4",
"property_id": "bd9c6fb24c31c772",
"property_type": "Apartment",
"province_abbreviation": "AB"
}
],
"error": "",
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 1,
"time_ms": 13,
"ui_info": {
"address": "302 610 17 Avenue SW",
"address_link": "ca/ab/calgary/beltline/302-610-17-avenue-sw",
"address_slug": "302-610-17-avenue-sw",
"city": "Calgary",
"city_id": "6ec95b53075d062c",
"city_link": "ca/ab/calgary",
"city_slug": "calgary",
"community": "Beltline",
"community_id": "ecc51da246c7dd4a",
"community_link": "ca/ab/calgary/beltline",
"community_slug": "beltline",
"country": "Canada",
"country_abbreviation": "CA",
"country_abbreviation_id": "9ace2b6431b7f1be",
"country_abbreviation_link": "ca",
"country_slug": "canada",
"parent_address": "610 17 Avenue SW",
"parent_property_id": "52a7d622eafe5319",
"property_id": "bd9c6fb24c31c772",
"province": "Alberta",
"province_abbreviation": "AB",
"province_abbreviation_id": "aae1f05a0f89d2c7",
"province_abbreviation_link": "ca/ab",
"province_slug": "alberta"
}
}
Compare each field returned against the client-supplied details (property type, lot size, closing value relative to estimate_sale_price) to produce a verified-or-needs-review flag.
For complete API documentation, see our Search API docs and Properties API docs.
Key capabilities for title operations
1. Address standardization
Convert any address format to a standardized address that matches a property Houski holds. Hit the /search endpoint with the raw input, take the first property_id back, then pull the canonical address components from /properties:
const houski_data = async (): Promise<SearchResponse> => {
// You must copy the SearchResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/search');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('max_results', '1');
url.searchParams.set('query', '123+main+st+calgary');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: SearchResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.02,
"data": [
{
"address": "123 Main Street",
"property_id": "aafadb43ded908a3"
}
],
"error": "",
"match_meta": [
{
"match_value": 0.7,
"property_id": "aafadb43ded908a3"
}
],
"price_quote": false,
"result_total": 1,
"time_ms": 63
}
The standardized components (address, city, province_abbreviation, postal_code) come back on the /properties follow-up against the resolved property_id.
The Search endpoint handles fuzzy address matching. See our Search API docs.
2. Geocoding for legal descriptions
Convert addresses to coordinates by first resolving the address through /search, then pulling the coordinates from /properties using the returned property_id:
const houski_data = async (): Promise<SearchResponse> => {
// You must copy the SearchResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/search');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('max_results', '1');
url.searchParams.set('query', '123+main+st+calgary+AB');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: SearchResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.02,
"data": [
{
"address": "123 Midcrest Crescent SE",
"property_id": "d5f6e3fa9a720e57"
}
],
"error": "",
"match_meta": [
{
"match_value": 0.73913044,
"property_id": "d5f6e3fa9a720e57"
}
],
"price_quote": false,
"result_total": 1,
"time_ms": 66
}
const houski_data = async (): Promise<PropertiesResponse> => {
// You must copy the PropertiesResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/properties');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('property_id_eq', 'bd9c6fb24c31c772');
url.searchParams.set('select', 'address,latitude,longitude');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: PropertiesResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.04,
"data": [
{
"address": "302 610 17 Avenue SW",
"latitude": 51.038193,
"longitude": -114.0751,
"property_id": "bd9c6fb24c31c772"
}
],
"error": "",
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 1,
"time_ms": 11,
"ui_info": {
"address": "302 610 17 Avenue SW",
"address_link": "ca/ab/calgary/beltline/302-610-17-avenue-sw",
"address_slug": "302-610-17-avenue-sw",
"city": "Calgary",
"city_id": "6ec95b53075d062c",
"city_link": "ca/ab/calgary",
"city_slug": "calgary",
"community": "Beltline",
"community_id": "ecc51da246c7dd4a",
"community_link": "ca/ab/calgary/beltline",
"community_slug": "beltline",
"country": "Canada",
"country_abbreviation": "CA",
"country_abbreviation_id": "9ace2b6431b7f1be",
"country_abbreviation_link": "ca",
"country_slug": "canada",
"parent_address": "610 17 Avenue SW",
"parent_property_id": "52a7d622eafe5319",
"property_id": "bd9c6fb24c31c772",
"province": "Alberta",
"province_abbreviation": "AB",
"province_abbreviation_id": "aae1f05a0f89d2c7",
"province_abbreviation_link": "ca/ab",
"province_slug": "alberta"
}
}
3. Property characteristic verification
Verify that property characteristics in legal documents match the records. Pull just the fields that appear in the file, then compare each to the document values. parcel_number is the assessing authority's own number for the property, written exactly as the authority writes it, which ties the file to the authority's records where the roll publishes it:
const houski_data = async (): Promise<PropertiesResponse> => {
// You must copy the PropertiesResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/properties');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('property_id_eq', 'bd9c6fb24c31c772');
url.searchParams.set('select', 'parcel_number,property_type,construction_year,interior_sq_m,land_area_sq_m,floor_above_ground,bedroom,bathroom_full');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: PropertiesResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.73,
"data": [
{
"address": "302 610 17 Avenue SW",
"bathroom_full": 1,
"bedroom": 2,
"construction_year": 1979,
"floor_above_ground": 1,
"interior_sq_m": 92.438484,
"land_area_sq_m": 0.0,
"parcel_number": "067878421",
"property_id": "bd9c6fb24c31c772",
"property_type": "Apartment"
}
],
"error": "",
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 1,
"time_ms": 9,
"ui_info": {
"address": "302 610 17 Avenue SW",
"address_link": "ca/ab/calgary/beltline/302-610-17-avenue-sw",
"address_slug": "302-610-17-avenue-sw",
"city": "Calgary",
"city_id": "6ec95b53075d062c",
"city_link": "ca/ab/calgary",
"city_slug": "calgary",
"community": "Beltline",
"community_id": "ecc51da246c7dd4a",
"community_link": "ca/ab/calgary/beltline",
"community_slug": "beltline",
"country": "Canada",
"country_abbreviation": "CA",
"country_abbreviation_id": "9ace2b6431b7f1be",
"country_abbreviation_link": "ca",
"country_slug": "canada",
"parent_address": "610 17 Avenue SW",
"parent_property_id": "52a7d622eafe5319",
"property_id": "bd9c6fb24c31c772",
"province": "Alberta",
"province_abbreviation": "AB",
"province_abbreviation_id": "aae1f05a0f89d2c7",
"province_abbreviation_link": "ca/ab",
"province_slug": "alberta"
}
}
Flag a discrepancy any time the document and database values differ outside a reasonable tolerance (10 sqm on lot size, exact match on year built).
4. Assessment value cross-reference
Compare closing values against assessment records by pulling the assessment fields and the model-based estimate in one call:
const houski_data = async (): Promise<PropertiesResponse> => {
// You must copy the PropertiesResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/properties');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('property_id_eq', 'bd9c6fb24c31c772');
url.searchParams.set('select', 'assessment_value,assessment_year,estimate_sale_price,estimate_list_price');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: PropertiesResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.42,
"data": [
{
"address": "302 610 17 Avenue SW",
"assessment_value": 301500,
"assessment_year": 2026,
"estimate_list_price": 271133,
"estimate_sale_price": 294333,
"property_id": "bd9c6fb24c31c772"
}
],
"error": "",
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 1,
"time_ms": 9,
"ui_info": {
"address": "302 610 17 Avenue SW",
"address_link": "ca/ab/calgary/beltline/302-610-17-avenue-sw",
"address_slug": "302-610-17-avenue-sw",
"city": "Calgary",
"city_id": "6ec95b53075d062c",
"city_link": "ca/ab/calgary",
"city_slug": "calgary",
"community": "Beltline",
"community_id": "ecc51da246c7dd4a",
"community_link": "ca/ab/calgary/beltline",
"community_slug": "beltline",
"country": "Canada",
"country_abbreviation": "CA",
"country_abbreviation_id": "9ace2b6431b7f1be",
"country_abbreviation_link": "ca",
"country_slug": "canada",
"parent_address": "610 17 Avenue SW",
"parent_property_id": "52a7d622eafe5319",
"property_id": "bd9c6fb24c31c772",
"province": "Alberta",
"province_abbreviation": "AB",
"province_abbreviation_id": "aae1f05a0f89d2c7",
"province_abbreviation_link": "ca/ab",
"province_slug": "alberta"
}
}
Compute the closing-to-assessment ratio and the closing-to-estimate ratio, then flag any outliers (ratios above 1.5 against assessment, or below 0.7 against the market estimate).
5. Batch verification for volume processing
For volume processing, loop the verification workflow over a list of closings in parallel. The underlying per-closing call is the same /properties lookup shown above.
Integration patterns
Direct API integration
For custom title production systems, wrap the three building blocks (find property, verify characteristics, cross-reference value) in a single service class. Each method calls the /search or /properties endpoint shown above, and the orchestration layer decides whether the file proceeds or routes for manual review.
Scheduled re-verification
Run a nightly or weekly batch job over your active-policy book to catch property characteristics that have changed since the original underwrite. We would loop through something like this for each policy:
const houski_data = async (): Promise<PropertiesResponse> => {
// You must copy the PropertiesResponse type declarations from the
// Houski API documentation to strongly type the response
const url = new URL('https://api.houski.ca/properties');
url.searchParams.set('api_key', 'YOUR_API_KEY');
url.searchParams.set('property_id_eq', 'bd9c6fb24c31c772');
url.searchParams.set('select', 'assessment_value,property_type,interior_sq_m');
const response = await fetch(url);
const data = await response.json();
return data;
}
(async () => {
let data: PropertiesResponse = await houski_data();
// Log the response
console.log(data);
})();
{
"cache_hit": false,
"cost_cents": 0.23000002,
"data": [
{
"address": "302 610 17 Avenue SW",
"assessment_value": 301500,
"interior_sq_m": 92.438484,
"property_id": "bd9c6fb24c31c772",
"property_type": "Apartment"
}
],
"error": "",
"pagination": {
"current_page": 1,
"has_next_page": false,
"has_previous_page": false,
"page_total": 1
},
"price_quote": false,
"result_total": 1,
"time_ms": 8,
"ui_info": {
"address": "302 610 17 Avenue SW",
"address_link": "ca/ab/calgary/beltline/302-610-17-avenue-sw",
"address_slug": "302-610-17-avenue-sw",
"city": "Calgary",
"city_id": "6ec95b53075d062c",
"city_link": "ca/ab/calgary",
"city_slug": "calgary",
"community": "Beltline",
"community_id": "ecc51da246c7dd4a",
"community_link": "ca/ab/calgary/beltline",
"community_slug": "beltline",
"country": "Canada",
"country_abbreviation": "CA",
"country_abbreviation_id": "9ace2b6431b7f1be",
"country_abbreviation_link": "ca",
"country_slug": "canada",
"parent_address": "610 17 Avenue SW",
"parent_property_id": "52a7d622eafe5319",
"property_id": "bd9c6fb24c31c772",
"province": "Alberta",
"province_abbreviation": "AB",
"province_abbreviation_id": "aae1f05a0f89d2c7",
"province_abbreviation_link": "ca/ab",
"province_slug": "alberta"
}
}
Compare the new values to what was on file at underwrite time. Flag any policy where the assessment, property type, or interior area has moved enough to warrant review.
Benefits for title operations
Reduced errors
Automated verification catches what manual review misses:
- Address format inconsistencies
- Property type mismatches
- Unusual value relationships
- Missing or incorrect characteristics
Faster processing
Multiple manual lookups happen in milliseconds:
- Instant address verification
- One-call property data retrieval
- Automated cross-referencing
- Batch processing
Lower costs
- Reduced analyst time per file
- Fewer errors to correct
- Scales without proportional staff increases
- Pay-per-use pricing
Improved client experience
- Same-day verifications
- Fewer callbacks for missing information
- Proactive issue identification
- Transparent verification status
Pricing for title companies
- Property lookups: Per-field pricing starting at fractions of a cent per field per property (see the API pricing page and per-field rates in the API fields documentation)
- Search/geocoding: billed per field per row, like every other endpoint
- Annual contracts: unlimited use for a flat annual fee, within fair use
A typical residential title file with address verification and property data retrieval runs under $0.50, a fraction of manual lookup time.
Getting started
- Get started with the API and get your API key
- Test the search endpoint with a few address lookups
- Review the properties endpoint and explore the available fields
- Build a verification workflow, starting with a single use case
- Contact us to discuss an annual contract
The future of title operations
Title is evolving toward instant verification and automated underwriting. Companies investing in API-based verification today will be positioned to offer faster, more accurate service as client expectations rise.
Ready to modernize verification? Explore Houski's API documentation or get an API key.
