A Laravel package for handling UK property data
lanos/laravel-property-data is a Laravel package for a laravel package for handling uk property data.
It currently has 2 GitHub stars and 0 downloads on Packagist (latest version v1.0.2).
Install it with composer require lanos/laravel-property-data.
Discover more Laravel packages by lanos
or browse all Laravel packages to compare alternatives.
Last updated
A comprehensive Laravel package for integrating with the PropertyData UK property data API. This package provides a clean, intuitive interface for accessing UK property market data, valuations, planning information, and area analytics.
This package integrates with the PropertyData API - a comprehensive UK property data service.
⚠️ Important: You need an API key to use this package.
👉 Get your API key at: https://propertydata.co.uk
📚 API Documentation: https://propertydata.co.uk/api/documentation
PropertyData provides access to:
✨ Key Features:
composer require lanos/laravel-property-data
The package will auto-register its service provider through Laravel's package discovery. To publish the configuration file:
php artisan vendor:publish --tag=property-data-config
This will create a config/property-data.php configuration file.
Add your PropertyData API key to your .env file:
PROPERTY_DATA_API_KEY=your-api-key-here
You can also configure optional settings:
# API Configuration
PROPERTY_DATA_API_URL=https://api.propertydata.co.uk
PROPERTY_DATA_API_TIMEOUT=30
# Logging
PROPERTY_DATA_LOGGING_ENABLED=true
PROPERTY_DATA_LOG_CHANNEL=stack
# Retry Configuration
PROPERTY_DATA_RETRY_ENABLED=true
PROPERTY_DATA_RETRY_ATTEMPTS=3
PROPERTY_DATA_RETRY_DELAY=1000
The configuration file (config/property-data.php) contains:
return [
'api' => [
'base_url' => env('PROPERTY_DATA_API_URL', 'https://api.propertydata.co.uk'),
'key' => env('PROPERTY_DATA_API_KEY', ''),
'timeout' => env('PROPERTY_DATA_API_TIMEOUT', 30),
'retry' => [
'enabled' => env('PROPERTY_DATA_RETRY_ENABLED', true),
'max_attempts' => env('PROPERTY_DATA_RETRY_ATTEMPTS', 3),
'delay' => env('PROPERTY_DATA_RETRY_DELAY', 1000), // milliseconds
],
],
'logging' => [
'enabled' => env('PROPERTY_DATA_LOGGING_ENABLED', true),
'channel' => env('PROPERTY_DATA_LOG_CHANNEL', config('logging.default')),
],
];
use PropertyData;
// Get property valuation
$valuation = PropertyData::valuationSale('SW1A 1AA', beds: 3, sqft: 1200);
// Get area demographics
$demographics = PropertyData::demographics(postcode: 'SW1A 1AA');
// Check planning applications
$planning = PropertyData::planningApplications(postcode: 'SW1A 1AA');
use Lanos\LaravelPropertyData\LaravelPropertyData;
class PropertyController extends Controller
{
public function __construct(
private LaravelPropertyData $propertyData
) {}
public function show(string $postcode)
{
$data = $this->propertyData->prices($postcode);
return view('property.show', compact('data'));
}
}
// Match address to UPRN
$uprns = PropertyData::addressMatchUprn('123 Example Street, London, SW1A 1AA');
// Lookup property by UPRN
$property = PropertyData::uprn('123456789012');
// Lookup multiple UPRNs
$properties = PropertyData::uprns(['123456789012', '123456789013']);
// Get Land Registry title for UPRN
$title = PropertyData::uprnTitle('123456789012');
// Current asking prices
$prices = PropertyData::prices('SW1A 1AA', page: 1, perPage: 20);
// Prices per square foot
$pricesPerSqf = PropertyData::pricesPerSqf('SW1A 1AA');
// Sold prices from Land Registry
$soldPrices = PropertyData::soldPrices('SW1A 1AA');
// Rental market statistics
$rents = PropertyData::rents('SW1A 1AA');
// HMO rent estimates
$hmoRents = PropertyData::rentsHmo('SW1A 1AA');
// Yield calculations
$yields = PropertyData::yields('SW1A 1AA');
// Price growth metrics
$growth = PropertyData::growth('SW1A 1AA');
// Property demand analytics
$demand = PropertyData::demand(postcode: 'SW1A 1AA');
// Instant sale valuation
$valuation = PropertyData::valuationSale('SW1A 1AA', beds: 3, sqft: 1200);
// Rent valuation
$rentValuation = PropertyData::valuationRent('SW1A 1AA');
// HMO valuation
$hmoValuation = PropertyData::valuationHmo('SW1A 1AA');
// Historical valuations
$history = PropertyData::valuationHistorical('SW1A 1AA', page: 1);
use Lanos\LaravelPropertyData\Enums\ProjectType;
use Lanos\LaravelPropertyData\Enums\FinishQuality;
// Development feasibility calculator
$feasibility = PropertyData::developmentCalculator(
postcode: 'SW1A 1AA',
purchasePrice: 500000,
sqftPreDevelopment: 1000,
sqftPostDevelopment: 1500,
projectType: ProjectType::REFURBISH,
finishQuality: FinishQuality::PREMIUM,
town: 'London' // optional
);
// Gross Development Value estimate
$gdv = PropertyData::developmentGdv(
postcode: 'SW1A 1AA',
town: 'London',
flat0: 0, // Studio flats
flat1: 2, // 1-bed flats
flat2: 3, // 2-bed flats
flat3: 1, // 3-bed flats
flat4: 0, // 4-bed flats
terracedHouse2: 0, // 2-bed terraced houses
terracedHouse3: 2, // 3-bed terraced houses
terracedHouse4: 1, // 4-bed terraced houses
terracedHouse5: 0 // 5-bed terraced houses
);
// Build cost data
$buildCost = PropertyData::buildCost('SW1A 1AA');
// Rebuild cost calculator
$rebuildCost = PropertyData::rebuildCost(
postcode: 'SW1A 1AA',
internalArea: 1200,
siteQuality: 'good',
propertyType: 'detached',
complexity: 'standard',
storeys: 2
);
use Lanos\LaravelPropertyData\Enums\DecisionRating;
// Planning applications
$planning = PropertyData::planningApplications(
postcode: 'SW1A 1AA',
decisionRating: DecisionRating::POSITIVE,
category: 'residential',
maxAge: 365
);
// Check if in Area of Outstanding Natural Beauty
$aonb = PropertyData::aonb(postcode: 'SW1A 1AA');
// Check if in conservation area
$conservation = PropertyData::conservationArea(postcode: 'SW1A 1AA');
// Check if in green belt
$greenBelt = PropertyData::greenBelt(postcode: 'SW1A 1AA');
// Check if in national park
$nationalPark = PropertyData::nationalPark(postcode: 'SW1A 1AA');
// Get listed buildings
$listedBuildings = PropertyData::listedBuildings('SW1A 1AA');
// Area type classification (rural/urban)
$areaType = PropertyData::areaType('SW1A 1AA');
// Council tax information
$councilTax = PropertyData::councilTax(postcode: 'SW1A 1AA');
// Crime statistics
$crime = PropertyData::crime(postcode: 'SW1A 1AA');
// Demographics
$demographics = PropertyData::demographics(postcode: 'SW1A 1AA');
// Flood risk
$floodRisk = PropertyData::floodRisk(postcode: 'SW1A 1AA');
// Household income
$income = PropertyData::householdIncome('SW1A 1AA');
// Internet speed
$internetSpeed = PropertyData::internetSpeed('SW1A 1AA');
// Local Housing Allowance rate
$lhaRate = PropertyData::lhaRate('SW1A 1AA');
// Population statistics
$population = PropertyData::population('SW1A 1AA');
// Political representation
$politics = PropertyData::politics('SW1A 1AA');
// PTAL score (London only)
$ptal = PropertyData::ptal('SW1A 1AA');
// Key statistics by postcode
$keyStats = PropertyData::postcodeKeyStats('SW1A 1AA');
// Nearby restaurants
$restaurants = PropertyData::restaurants(
postcode: 'SW1A 1AA',
page: 1,
perPage: 20
);
// Nearby schools
$schools = PropertyData::schools(postcode: 'SW1A 1AA');
// Land Registry documents
$documents = PropertyData::landRegistryDocuments(
title: 'DN123456',
uprn: '123456789012'
);
// Site plan documents
$sitePlans = PropertyData::sitePlanDocuments('SW1A 1AA', page: 1, perPage: 20);
// Mortgage calculator
$mortgage = PropertyData::mortgageCalculator(
price: 500000,
deposit: 100000,
rate: 5.5,
termYears: 25
);
// Current mortgage rates
$rates = PropertyData::mortgageRates();
// Stamp Duty calculator
$stampDuty = PropertyData::stampDutyCalculator(
price: 500000,
buyerType: 'first-time'
);
// Get API credits information
$credits = PropertyData::accountCredits();
// Get account documents
$documents = PropertyData::accountDocuments(page: 1, perPage: 20);
// Test API connection
$isConnected = PropertyData::testConnection();
use PropertyData;
use Lanos\LaravelPropertyData\Enums\ProjectType;
use Lanos\LaravelPropertyData\Enums\FinishQuality;
class PropertyInvestmentService
{
public function analyzeInvestment(string $postcode, float $purchasePrice)
{
// Get current market data
$prices = PropertyData::prices($postcode);
$yields = PropertyData::yields($postcode);
$demand = PropertyData::demand(postcode: $postcode);
// Get area information
$crime = PropertyData::crime(postcode: $postcode);
$schools = PropertyData::schools(postcode: $postcode);
$demographics = PropertyData::demographics(postcode: $postcode);
// Calculate development potential
$feasibility = PropertyData::developmentCalculator(
postcode: $postcode,
purchasePrice: $purchasePrice,
sqftPreDevelopment: 1000,
sqftPostDevelopment: 1400,
projectType: ProjectType::REFURBISH,
finishQuality: FinishQuality::MEDIUM
);
return [
'market' => [
'prices' => $prices,
'yields' => $yields,
'demand' => $demand,
],
'area' => [
'crime' => $crime,
'schools' => $schools,
'demographics' => $demographics,
],
'development' => $feasibility,
];
}
}
use PropertyData;
class PropertyDueDiligenceService
{
public function performDueDiligence(string $uprn)
{
// Get property details
$property = PropertyData::uprn($uprn);
$title = PropertyData::uprnTitle($uprn);
// Get planning information
$planning = PropertyData::planningApplications(
postcode: $property['postcode']
);
// Check restrictions
$checks = [
'conservation_area' => PropertyData::conservationArea(
postcode: $property['postcode']
),
'green_belt' => PropertyData::greenBelt(
postcode: $property['postcode']
),
'listed_buildings' => PropertyData::listedBuildings(
$property['postcode']
),
'flood_risk' => PropertyData::floodRisk(
postcode: $property['postcode']
),
];
// Get documents
$documents = PropertyData::landRegistryDocuments(
uprn: $uprn
);
return [
'property' => $property,
'title' => $title,
'planning' => $planning,
'restrictions' => $checks,
'documents' => $documents,
];
}
}
use PropertyData;
class LocationSearchService
{
public function searchByCoordinates(float $lat, float $lng)
{
$location = "$lat,$lng";
// Get area data using coordinates
$demand = PropertyData::demand(location: $location);
$agents = PropertyData::agents(location: $location);
$crime = PropertyData::crime(location: $location);
$restaurants = PropertyData::restaurants(location: $location);
$schools = PropertyData::schools(location: $location);
return compact('demand', 'agents', 'crime', 'restaurants', 'schools');
}
public function searchByWhat3Words(string $w3w)
{
// Get area data using What3Words
$demand = PropertyData::demand(w3w: $w3w);
$planning = PropertyData::planningApplications(w3w: $w3w);
return compact('demand', 'planning');
}
}
The package includes comprehensive error handling with specific exception types:
PropertyDataApiException - Base exception for all API errorsPropertyDataAuthenticationException - Invalid API key or authentication failedPropertyDataConnectionException - Network connection issuesPropertyDataServerException - API server errors (5xx responses)PropertyDataRateLimitException - Rate limit exceeded (currently unused as API has no rate limits)use Lanos\LaravelPropertyData\Exceptions\PropertyDataAuthenticationException;
use Lanos\LaravelPropertyData\Exceptions\PropertyDataConnectionException;
use Lanos\LaravelPropertyData\Exceptions\PropertyDataApiException;
try {
$data = PropertyData::prices('SW1A 1AA');
} catch (PropertyDataAuthenticationException $e) {
// Handle authentication error
Log::error('Invalid API key: ' . $e->getMessage());
} catch (PropertyDataConnectionException $e) {
// Handle connection error
Log::error('Connection failed: ' . $e->getMessage());
} catch (PropertyDataApiException $e) {
// Handle general API error
Log::error('API error: ' . $e->getMessage());
}
The package validates all inputs before making API calls:
try {
// This will throw an InvalidArgumentException
$data = PropertyData::prices('INVALID_POSTCODE');
} catch (\InvalidArgumentException $e) {
// Handle validation error
echo $e->getMessage(); // "Invalid UK postcode format..."
}
The package automatically retries failed requests for transient errors:
composer test
composer test-coverage
composer analyse
composer format
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details on how to contribute to this package.
composer installgit checkout -b feature/my-featurecomposer testIf you discover any security-related issues, please email [email protected] instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
⚠️ IMPORTANT NOTICE
This package is an independent integration library for the PropertyData API. We are not affiliated with, endorsed by, or connected to PropertyData or its parent company.
For official API documentation and support, please visit https://propertydata.co.uk
Please ensure you comply with PropertyData's terms of service and data usage policies when using this package. The package authors assume no responsibility for how you use the data obtained through the API.
This package is provided "as is" without warranty of any kind, either expressed or implied. See the LICENSE file for full disclaimer of warranties.