mlsapi
The official Python client library for mlsapi.dev.
Access real-time MLS listing data, property intelligence, CapEx lifecycle analysis, AI-generated marketing copy, and the complete suite of Studio Visual AI generative tools (virtual staging, twilight conversion, decluttering, 3D dollhouse floor plans, 4K upscaling, ad creatives, and video generation).
Table of Contents
- Features
- Installation
- Quick Start
- Configuration & Authentication
- Core Features & Code Examples
- 1. Real-Time MLS Listing Lookup & Ingestion
- 2. Property Intelligence & CapEx Analysis
- 3. Marketing Content Generation
- 4. Media Upload to Global CDN
- 5. Virtual Room Staging (29 Architectural Styles)
- 6. Day-to-Dusk Twilight & Exterior Enhancement
- 7. Declutter & Clean Space
- 8. De-Staging (Empty Room) & Floor Restoration
- 9. Furniture & Surface Material Replacement
- 10. 3x3 Designer Wall Paint Swatches
- 11. 2D Blueprint to 3D Isometric Dollhouse
- 12. 4K Super-Resolution Upscaling
- 13. Branded Multi-Placement Ad Creatives
- 14. AI Video Walkthroughs & Voice/Subtitle Polish
- Asynchronous Jobs & Progress Callbacks
- Error Handling
- Supported Presets Reference
- License
Features
- Dual Sync & Async Interfaces: Native synchronous
MlsApiClientand asyncAsyncMlsApiClientfor high-throughputasyncioapplications. - Deep Type Safety: Pydantic v2 domain models with full IDE autocompletion, type hinting, and runtime validation.
- Smart Asynchronous Polling: Auto-waiting helper methods (
*_and_wait(...)) with exponential backoff, jitter, and real-time progress callbacks. - Resilient Networking: Built on
httpxwith automatic connection pooling and smart retries on HTTP 429 rate limits and 5xx server errors. - Complete Studio Coverage: First-class access to all 21+ Studio generative visual endpoints.
Installation
Install via pip, uv, or poetry:
# pip
pip install pymlsapi
# uv
uv add pymlsapi
# poetry
poetry add pymlsapi
Requires Python 3.9+.
Quick Start
Synchronous Example
import os
from pymlsapi import MlsApiClient
# Initialize the client with your API key
mls = MlsApiClient(api_key=os.environ.get("MLSAPI_KEY"))
# 1. Fetch normalized MLS listing data
listing = mls.listings.get_and_wait("A12079565")
print(f"Property: {listing.address.formatted} - ${listing.price:,.2f}")
print(f"Downloaded {listing.photo_count} photos: {listing.photos[0]}")
# 2. Perform AI Virtual Staging on an empty room photo
staged = mls.studio.staging.stage_and_wait(
photo_url=listing.photos[0],
room_type="living_room",
style="scandinavian",
custom_staging_instructions="Oak dining table, bouclé accent chairs, fiddle-leaf fig tree",
)
print(f"Staged photo ready: {staged.staged_photo_url}")
print(f"Before/after comparison: {staged.before_after_comparison_url}")
Asynchronous (asyncio) Example
import asyncio
import os
from pymlsapi import AsyncMlsApiClient
async def main():
async with AsyncMlsApiClient(api_key=os.environ.get("MLSAPI_KEY")) as mls:
# Ingest listing and synthesize intelligence concurrently
listing_task = mls.listings.get_and_wait("A12079565")
intel_task = mls.intelligence.get("A12079565", investor_mode=True)
listing, intel = await asyncio.gather(listing_task, intel_task)
print(f"Listing: {listing.address.city}, {listing.address.state}")
print(f"Gross Yield: {intel.llm_derived_intelligence.investor_insights.estimated_gross_yield_pct}%")
asyncio.run(main())
Configuration & Authentication
Obtain your API key from the mlsapi.dev Dashboard.
from pymlsapi import MlsApiClient
mls = MlsApiClient(
api_key="sk_live_...", # Secret API key (or MLSAPI_KEY env var)
environment="live", # "live" (production) or "test" (sandbox)
base_url="https://api.mlsapi.dev", # Optional custom base URL or staging endpoint
timeout_seconds=60.0, # HTTP request timeout (default: 60s)
max_retries=3, # Automatic retries on rate limits (429) & 5xx errors
)
Core Features & Code Examples
1. Real-Time MLS Listing Lookup & Ingestion
Ingest property records by MLS number. If the property is not cached, the engine enqueues live scraping and photo downloading.
# Auto-wait until scraping completes (recommended)
listing = mls.listings.get_and_wait(
"A12079565",
timeout_seconds=45.0,
on_progress=lambda job: print(f"Ingestion step: {job.step}"),
)
print(listing.address.city, listing.specifications.beds, listing.specifications.baths_full)
print(f"Downloaded {listing.photo_count} high-res photos: {listing.photos}")
# Or handle the asynchronous job tracker manually
response = mls.listings.get("A12079565")
if hasattr(response, "status") and response.status == "processing":
print(f"Ingestion job queued with tracker ID: {response.job_id}")
2. Property Intelligence & CapEx Analysis
Synthesize public tax records, historical ownership, school zoning, replacement horizons for major structural systems (roof, HVAC, water heater, impact windows), and investor yields.
intel = mls.intelligence.get(
"A12079565",
include_llm=True, # Deep AI analysis of remarks and conditions
investor_mode=True, # Include estimated rent, gross yield, and HOA flags
)
insights = intel.llm_derived_intelligence.investor_insights
capex = intel.llm_derived_intelligence.systems_and_capex
print(f"Estimated Monthly Rent: ${insights.estimated_monthly_rent.median:,.2f}")
print(f"Gross Yield: {insights.estimated_gross_yield_pct}%")
print(f"Roof Age & Condition: {capex.roof.age_years} years - {capex.roof.condition}")
print(f"Impact windows detected: {capex.storm_protection.has_impact_windows}")
3. Marketing Content Generation
Generate multi-channel marketing campaigns tailored by tone, target audience, and channel format.
copy = mls.content.generate(
"A12079565",
outputs=["social", "email_blast", "video_script", "flyer_bullets", "mls_remarks"],
social_platforms=["instagram", "linkedin", "facebook", "tiktok"],
tone="luxury",
target_audience="High-net-worth buyers relocating to South Florida",
)
# Access typed content
print("Instagram Caption:\n", copy.content.social.instagram.caption)
print("Instagram Hashtags:\n", copy.content.social.instagram.hashtags)
print("Video Script Hook:\n", copy.content.video_script.hook)
print("Optimized MLS Remarks:\n", copy.content.mls_remarks)
4. Media Upload to Global CDN
Upload local image files, binary bytes, or open file objects directly to the mlsapi.dev CDN to use as inputs for any Studio operation.
from pathlib import Path
# 1. Upload from a local filesystem path
upload1 = mls.studio.upload(Path("./photos/vacant_living_room.jpg"))
print("CDN URL:", upload1.url)
# 2. Upload from raw bytes
with open("./photos/blueprint.png", "rb") as f:
upload2 = mls.studio.upload(
f.read(),
filename="blueprint.png",
content_type="image/png",
)
print("Uploaded blueprint:", upload2.url)
5. Virtual Room Staging (29 Architectural Styles)
Furnish vacant room photos with photorealistic staging adhering to real estate staging standards.
staged = mls.studio.staging.stage_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/vacant_living_room.jpg",
room_type="living_room",
style="luxury", # Choose from 29 styles (e.g. 'modern', 'japandi', 'coastal')
preserve_flooring=True, # Keep original hardwood/tile flooring
custom_staging_instructions="White boucle sectional, travertine coffee table, minimalist wall art",
)
print("Staged image:", staged.staged_photo_url)
print("Before/after slider:", staged.before_after_comparison_url)
print("Staging manifest:", staged.staging_manifest)
6. Day-to-Dusk Twilight & Exterior Enhancement
Transform daytime exterior photos into dramatic golden-hour twilight scenes with warm interior illumination, or enhance sunny curb appeal.
# 1. Twilight Day-to-Dusk conversion
twilight = mls.studio.staging.twilight_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/exterior_day.jpg",
mode="day_to_dusk", # Or 'blue_sky_replace'
)
print("Twilight exterior:", twilight.enhanced_photo_url)
# 2. Exterior enhancements (blue sky, green lawn, pool cleaning)
enhanced = mls.studio.enhance.exterior_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/exterior_overcast.jpg",
enhancements=["blue_sky", "green_grass", "clean_pool", "tidy_garden"],
)
print("Enhanced curb appeal:", enhanced.enhanced_photo_url)
7. Declutter & Clean Space
Remove tenant clutter, wires, boxes, children's toys, and moving messes while strictly keeping walls, floors, and primary structural architecture intact.
clean = mls.studio.staging.declutter_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/cluttered_kitchen.jpg",
room_type="kitchen",
removal_targets=["dishes", "refrigerator magnets", "trash cans", "countertop appliances"],
)
print("Clean photo:", clean.decluttered_photo_url)
print("Items removed:", clean.items_removed)
8. De-Staging (Empty Room) & Floor Restoration
Strip out outdated furniture to present prospective buyers with a clean architectural canvas, with optional floor restoration.
emptied = mls.studio.staging.empty_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/dated_bedroom.jpg",
room_type="bedroom",
restore_flooring="hardwood", # 'hardwood' | 'tile' | 'carpet' | 'polished_concrete'
)
print("Empty room canvas:", emptied.empty_photo_url)
9. Furniture & Surface Material Replacement
Replace outdated furniture items with modern pieces or resurface materials like kitchen countertops and flooring.
# 1. Precision furniture swap
new_sofa = mls.studio.staging.replace_furniture_and_wait(
room_photo_url="https://cdn.mlsapi.dev/uploads/living.jpg",
target_furniture="sofa",
product_description="Low-profile minimalist Italian cream leather sofa",
# Or pass an exact product catalog photo:
# reference_product_image_url="https://example.com/catalog-sofa.jpg",
)
print("Updated sofa photo:", new_sofa.result_photo_url)
# 2. Surface material replacement
new_kitchen = mls.studio.staging.replace_material_and_wait(
room_photo_url="https://cdn.mlsapi.dev/uploads/kitchen.jpg",
surface_type="countertops",
material_preset="Calacatta Gold Italian Marble with subtle grey and gold veining",
)
print("Updated kitchen countertops:", new_kitchen.result_photo_url)
10. 3x3 Designer Wall Paint Swatches
Test curated designer paint colors on room walls with an instant 3x3 comparison grid.
swatches = mls.studio.staging.wall_colors_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/living_room.jpg",
palette_preset="popular_neutrals", # 'popular_neutrals' | 'modern_earth' | 'coastal_breeze' | 'moody_darks'
)
print("3x3 comparison grid:", swatches.comparison_grid_3x3_url)
for swatch in swatches.swatch_results:
print(f"Color: {swatch.color_name} ({swatch.hex}) -> {swatch.image_url}")
11. 2D Blueprint to 3D Isometric Dollhouse
Convert 2D floor plans, architectural blueprints, or hand sketches into 3D isometric cutaway dollhouse renders.
# Step 1: Analyze floor plan structural geometry
analysis = mls.studio.floorplan.analyze(
floorplan_image_url="https://cdn.mlsapi.dev/uploads/floorplan.png",
style="modern",
)
print(f"Rooms detected: {analysis.spatial_summary.total_rooms_detected}")
# Step 2: Render 3D isometric dollhouse view
dollhouse = mls.studio.floorplan.render_3d_and_wait(
floorplan_image_url="https://cdn.mlsapi.dev/uploads/floorplan.png",
style="modern",
include_room_closeups=True,
)
print("3D Dollhouse Render:", dollhouse.isometric_3d_dollhouse_url)
for closeup in dollhouse.room_renders:
print(f"Room {closeup.room_name}: {closeup.image_url}")
12. 4K Super-Resolution Upscaling
Upscale low-resolution or compressed MLS photos up to 4K resolution with AI detail reconstruction.
upscaled = mls.studio.enhance.upscale_and_wait(
image_url="https://cdn.mlsapi.dev/uploads/lowres_photo.jpg",
scale_factor=4, # 2 or 4
enhance_details=True,
)
print("4K Upscaled image:", upscaled.upscaled_image_url)
print("Target resolution:", upscaled.target_resolution)
13. Branded Multi-Placement Ad Creatives
Generate compliant real estate ad creatives with agent branding kits, MLS property badges, and typography across all social and print dimensions.
ads = mls.studio.creatives.generate_and_wait(
mls_id="A12079565",
trigger="just_listed", # 'just_listed' | 'open_house' | 'price_improved' | 'just_sold'
direction="magazine", # 'magazine' | 'bold' | 'warm'
placements=["feed_portrait", "square", "link", "flyer"],
brand_kit={
"agent_name": "Sarah Connor",
"brokerage_name": "Compass Beverly Hills",
"phone": "(310) 555-0199",
"primary_brand_color": "#0F172A",
"agent_headshot_url": "https://cdn.example.com/sarah-headshot.jpg",
},
)
print("1:1 Square Feed Ad:", ads.creatives.get("square").image_url)
print("9:16 Vertical Story Ad:", ads.creatives.get("feed_portrait").image_url)
print("Fair Housing compliance passed:", ads.compliance.fair_housing_passed)
14. AI Video Walkthroughs & Voice/Subtitle Polish
Polish realtor walkthrough videos with studio voice leveling, Hormozi-style animated captions, and automatic vertical 9:16 re-framing.
polished_video = mls.studio.video.enhance_and_wait(
video_url="https://cdn.mlsapi.dev/uploads/raw_walkthrough.mp4",
features={
"studio_voice": True, # Wind/echo cleanup & voice mastering
"animated_subtitles": True, # Word-by-word dynamic animated subtitles
"smart_reframe": True, # Auto-track agent and reframe to 9:16
},
subtitle_style={
"font_theme": "hormozi_bold",
"primary_color": "#FFFFFF",
"highlight_color": "#FFDE59",
},
export_aspect_ratios=["9:16", "16:9"],
)
print("Reels / TikTok Video:", polished_video.mastered_videos[0].url)
Asynchronous Jobs & Progress Callbacks
Every Studio operation returns immediately with an HTTP 202 StudioJob when using the standard method (e.g. stage(...)), or polls until completion when using the *_and_wait(...) companion method.
Custom Polling Options & Progress Hook
def on_progress(job):
print(f"[{job.progress_percentage}%] Step: {job.current_step}")
result = mls.studio.staging.stage_and_wait(
photo_url="https://cdn.mlsapi.dev/uploads/room.jpg",
style="japandi",
poll_interval=2.0, # Poll every 2.0 seconds (default: 2.0s)
timeout_seconds=120.0, # Maximum wait time (default: 90.0s)
on_progress=on_progress, # Optional progress callback
)
Manual Job Tracking
# Dispatch without waiting
job = mls.studio.staging.stage(photo_url="https://cdn.mlsapi.dev/uploads/room.jpg")
print(f"Track job later: {job.job_id}")
# Check status later
current_status = mls.studio.jobs.get(job.job_id)
print(f"Status: {current_status.status}, progress: {current_status.progress_percentage}%")
# Or wait for it when ready
completed_job = mls.studio.jobs.wait_for(job.job_id, timeout_seconds=90.0)
print("Result URL:", completed_job.result.staged_photo_url)
Error Handling
All API errors inherit from MlsApiError and expose the HTTP status code, error code, and server message.
from pymlsapi.errors import (
MlsApiError,
AuthenticationError,
NotFoundError,
RateLimitError,
InsufficientCreditsError,
JobTimeoutError,
)
try:
listing = mls.listings.get_and_wait("INVALID_ID")
except AuthenticationError as e:
print("Invalid API Key:", e.message)
except NotFoundError as e:
print("Listing or resource not found:", e.message)
except RateLimitError as e:
print(f"Rate limited. Quota resets in {e.retry_after_seconds}s")
except InsufficientCreditsError as e:
print("Insufficient credits in workspace balance. Top up at https://mlsapi.dev/billing")
except JobTimeoutError as e:
print(f"Job polling timed out after {e.timeout_seconds}s")
except MlsApiError as e:
print(f"API Error [{e.code}]: {e.message}")
Supported Presets Reference
Interior Design Styles (29 Presets)
modern |
luxury |
scandinavian |
japandi |
industrial |
bohemian |
minimalist |
coastal |
mid_century_modern |
art_deco |
farmhouse |
mediterranean |
contemporary |
rustic |
transitional |
french_country |
hollywood_regency |
eclectic |
zen |
bauhaus |
victorian |
tropical |
modern_craftsman |
southwestern |
wabi_sabi |
shabby_chic |
chalet |
urban_loft |
custom |
Architectural Room Types (12 Types)
living_room, bedroom, primary_bedroom, dining_room, kitchen, bathroom, patio, outdoor_patio, home_office, entryway, basement, commercial_lobby.
License
MIT © mlsapi.dev
Metadata
Release files for pymlsapi 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pymlsapi-0.1.0.tar.gz | 63.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pymlsapi-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 102.6 kB
Release files / pymlsapi-0.1.0.tar.gz
| Download URL | pymlsapi-0.1.0.tar.gz |
|---|---|
| Size | 63.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8ea1640558a5feb89a681802f69875c09f4597a260bc610afbf8e123b489fe5c
|
|
BLAKE2b-256 checksum How to use checksums |
b04b4bf2952e4d2b78a7ae85351084e38296890ade39131a4254782356fd6a60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pymlsapi-0.1.0-py3-none-any.whl
| Download URL | pymlsapi-0.1.0-py3-none-any.whl |
|---|---|
| Size | 39.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1d2580fbec70d9728eef8beeb9f5ab2669ed5a7295c6a7ead2d3e247a8e8a128
|
|
BLAKE2b-256 checksum How to use checksums |
ece572a0ea42a5cd6a0429337c5bdf231a764011259da96e0963dc2873500370
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|