Documentation

Redfin CLI

redfin-pp-cli

Install

npx -y @mvanhorn/printing-press-library install redfin

Installs the CLI binary and the agent skill for Claude Code, Codex, Cursor, Gemini CLI, Copilot, and more. Add --cli-only or --skill-only for one half. Requires Node.

Documentation

Stingray-backed Redfin CLI with the workflows the website can't do — saved-search diff, sold-price trends, $/sqft ranking, and offline SQL.

Search homes for sale via Redfin's internal Stingray endpoints from the terminal, sync results to a local SQLite store, and run the workflows the website never built: diff a saved search week-over-week with watch, rank by $/sqft net of HOA with rank, pull sold comps for a subject property with comps, surface price drops or stale listings with drops, and overlay market trends across multiple cities with trends. Every command is --json / --select-shaped so an agent can pipe the output without burning context.

Learn more at Redfin.

Created by @rderwin (rderwin).

Authentication

No authentication required. The Stingray endpoints are the same ones Redfin's web app uses, served unauthenticated to US IPs. Account-only features (saved homes, alerts, agent dashboard) are intentionally out of scope. Surf with Chrome TLS fingerprint clears AWS-WAF protection at runtime; cliutil.AdaptiveLimiter handles per-IP rate limits with exponential backoff.

Quick Start

# Verify connectivity and US-IP geo access (Stingray is US-only).
redfin-pp-cli doctor

# Resolve the canonical region_id you need for every search.
redfin-pp-cli region resolve "Austin, TX" --json

# Search — verifies Stingray endpoints respond and JSON output is well-formed.
redfin-pp-cli homes --region-id 30772 --region-type 6 --beds-min 3 --price-max 600000 --status for-sale --json --limit 10

# Persist that search to the local store under slug 'austin-3br'.
redfin-pp-cli sync-search austin-3br --region-id 30772 --region-type 6 --beds-min 3 --price-max 600000 --status for-sale

# Rank synced listings by net-HOA $/sqft — the metric Redfin's sort never offers.
redfin-pp-cli rank --by price-per-sqft --net-hoa --region-id 30772 --region-type 6 --json --limit 10

# After a few days — diff against the previous sync and emit NEW / REMOVED / PRICE-CHANGED / STATUS-CHANGED.
redfin-pp-cli watch austin-3br --since 7d --json

# One-shot market snapshot: active, pending, sold-90d, medians, % with price drops.
redfin-pp-cli summary 30772 --json

Unique Features

These capabilities aren't available in any other tool for this API.

Time-series intelligence

  • watch — Re-run a saved gis search and surface what's NEW, REMOVED, PRICE-CHANGED, or STATUS-CHANGED since the last sync.

    Pick this when an agent is tracking a buyer's shortlist over time and needs a reproducible 'what changed' digest.

    redfin-pp-cli watch austin-3br --since 7d --json
    
  • drops — List active listings whose price dropped by N% in a window, OR whose days-on-market exceed a threshold.

    Pick this when timing the market or surfacing lowball candidates before tour scheduling.

    redfin-pp-cli drops --region-id 30772 --region-type 6 --since 7d --min-pct 3 --dom-min 30 --json
    

Local-store math

  • rank — Rank synced listings by price-per-sqft, with optional HOA-fee subtraction over a 5-year horizon.

    Pick this when value-per-dollar is the goal and HOA-heavy condos must compete fairly against single-family.

    redfin-pp-cli rank --by price-per-sqft --net-hoa --region-id 30772 --region-type 6 --json --limit 25
    

Shortlist workflows

  • compare — Pull 2-8 listings through the combined Stingray detail endpoint and emit aligned columnar output (price, $/sqft, beds, baths, lot, year, schools, AVM delta, last sale, taxes).

    Pick this when narrowing a shortlist; the wide table makes school-rating and AVM-delta differences obvious.

    redfin-pp-cli compare <your-listing-url> <another-listing-url> --json
    
  • comps — For a subject listing, derive a circular polygon from --radius, run a sold-status search, filter by --sqft-tol and --bed-match, return the ranked comp set.

    Pick this when an agent needs to pull comparable sales for a buyer offer; collapses 20 minutes of polygon-clicking into one command.

    redfin-pp-cli comps <your-listing-url> --radius 0.5 --sqft-tol 15 --months 6 --bed-match --json
    

Cross-market joins

  • rank — Union synced listings across multiple region slugs and rank across the entire set, deduped by listing URL.

    Pick this when an agent needs a single ranked feed across multiple metros without writing a fan-out loop.

    redfin-pp-cli rank --regions 30772,30773,30774 --by price-per-sqft --beds-min 3 --price-max 600000 --json --limit 25
    
  • trends — Pull aggregate-trends for N regions and emit one tidy long table (region × month × metric) over a window.

    Pick this when a relocator is comparing cities and needs the medians overlaid on the same axis.

    redfin-pp-cli trends --regions 30743,18028,30739 --metric median-sale --period 24 --json
    

Bulk extraction

  • export — Slice the price space into bands, page-walk gis-csv per band until each returns under 350 rows, dedupe on listing URL, emit one CSV/JSON.

    Pick this when you need every comp for a year, not the first 350 sorted by relevance.

    redfin-pp-cli export --region-slug "city/30772/TX/Austin" --status sold --year 2024 --csv > austin-sold-2024.csv
    

Aggregations

  • summary — Single command: active count, pending count, sold-90d count, median list, median sold, median DOM, median $/sqft, % with price drops, plus a trends snapshot.

    Pick this when an agent needs the one-shot snapshot of a market for a buyer brief.

    redfin-pp-cli summary 30772:6 --json
    
  • appreciation — For all child neighborhoods under a parent metro, call aggregate-trends and rank by YoY median-sale % change.

    Pick this when a relocator or investor needs the 'where in this metro is hottest' answer.

    redfin-pp-cli appreciation --parent "city/30772/TX/Austin" --period 12 --json --limit 10
    

Usage

Run redfin-pp-cli --help for the full command reference and flag list.

Commands

homes

Search Redfin homes for sale via the internal Stingray /api/gis JSON endpoint.

  • redfin-pp-cli homes list - Run a Stingray gis search and return parsed listing rows from the JSON map payload. Strip the {}&& CSRF prefix before decoding.

listing

Fetch full listing detail by combining initialInfo, aboveTheFold, and belowTheFold Stingray calls.

  • redfin-pp-cli listing initial - First Stingray call for a listing — returns the canonical listingId and propertyId from the URL path.

market

Aggregate market trends for a region (median sale price, days on market, supply, list-to-sale ratio) over a window.

  • redfin-pp-cli market trends - Fetch aggregate-trends JSON for one region and period (months).

Output Formats

# Human-readable table (default in terminal, JSON when piped)
redfin-pp-cli homes

# JSON for scripting and agents
redfin-pp-cli homes --json

# Filter to specific fields
redfin-pp-cli homes --json --select id,name,status

# Dry run — show the request without sending
redfin-pp-cli homes --dry-run

# Agent mode — JSON + compact + no prompts in one flag
redfin-pp-cli homes --agent

Agent Usage

This CLI is designed for AI agent consumption:

  • Non-interactive - never prompts, every input is a flag
  • Pipeable - --json output to stdout, errors to stderr
  • Filterable - --select id,name returns only fields you need
  • Previewable - --dry-run shows the request without sending
  • Read-only by default - this CLI does not create, update, delete, publish, send, or mutate remote resources
  • Offline-friendly - sync/search commands can use the local SQLite store when available
  • Agent-safe by default - no colors or formatting unless --human-friendly is set

Exit codes: 0 success, 2 usage error, 3 not found, 5 API error, 7 rate limited, 10 config error.

Freshness

This CLI owns bounded freshness only for registered store-backed read command paths. In --data-source auto mode, covered commands check the local SQLite store before serving results; stale or missing resources trigger a bounded refresh, and refresh failures fall back to the existing local data with a warning. --data-source local never refreshes, and --data-source live reads the API without mutating the local store.

Set REDFIN_NO_AUTO_REFRESH=1 to disable the pre-read freshness hook while preserving the selected data source.

Covered command paths: none. homes is a live per-call search; the local store is populated by sync-search / watch only.

JSON outputs that use the generated provenance envelope include freshness metadata at meta.freshness. This metadata describes the freshness decision for the covered command path; it does not claim full historical backfill or API-specific enrichment.

Health Check

redfin-pp-cli doctor

Verifies configuration and connectivity to the API.

Configuration

Config file: ~/.config/redfin-pp-cli/config.toml

Environment variables:

  • REDFIN_CONFIG — override the config file path
  • REDFIN_BASE_URL — override the base API URL (default https://www.redfin.com)
  • REDFIN_NO_AUTO_REFRESH=1 — disable the pre-read freshness hook (read commands won't auto-refresh stale local data)
  • REDFIN_FEEDBACK_ENDPOINT — when set, feedback entries can be POSTed to this URL
  • REDFIN_FEEDBACK_AUTO_SEND=true — auto-send feedback entries when the endpoint is configured
  • NO_COLOR — disable colored output (also responds to --no-color)

The local SQLite store lives at ~/.local/share/redfin-pp-cli/data.db.

Cookbook

# Watch a saved search weekly — agent-friendly digest
redfin-pp-cli sync-search austin-3br --region-id 30772 --region-type 6 --beds-min 3 --price-max 600000 --status for-sale
redfin-pp-cli watch austin-3br --since 7d --json

# Sold comps for a subject listing within 0.5mi, ±15% sqft, last 6 months
redfin-pp-cli comps /TX/Austin/123-Main/home/12345 --radius 0.5 --sqft-tol 15 --months 6 --bed-match --json

# Rank by net-HOA $/sqft across multiple regions
redfin-pp-cli rank --regions 30772:6,30773:6,30774:6 --by price-per-sqft --net-hoa --beds-min 3 --json --limit 25

# Surface listings with a >=3% price drop or >30 days on market
redfin-pp-cli drops --region-id 30772 --region-type 6 --since 7d --min-pct 3 --dom-min 30 --json

# Side-by-side compare 2-8 listings (price, $/sqft, schools, AVM delta)
redfin-pp-cli compare \
  /TX/Austin/123-Main/home/12345 \
  /TX/Austin/456-Elm/home/67890 \
  --json

# Cross-metro trends overlay (period is months as integer)
redfin-pp-cli trends --regions 30743:6,18028:6,30739:6 --metric median-sale --period 24 --json

# Hottest neighborhoods within a metro by YoY median-sale appreciation
redfin-pp-cli appreciation --parent "city/30772/TX/Austin" --period 12 --json

# One-shot market snapshot for a region
redfin-pp-cli summary 30772 --json

# Bulk export all sold listings for a year (price-banded, dedup'd, CSV-shaped)
redfin-pp-cli export --region-slug "city/30772/TX/Austin" --status sold --year 2024 --format csv > austin-sold-2024.csv

# Pipe ranked output into jq for further filtering
redfin-pp-cli rank --by price-per-sqft --region-id 30772 --region-type 6 --json --limit 100 \
  | jq '[.[] | select(.beds >= 4 and .price_per_sqft < 350)]'

# Use a saved profile to bake in repeating flags (region, filters)
redfin-pp-cli profile save austin-3br --region-id 30772 --region-type 6 --beds-min 3
redfin-pp-cli homes --profile austin-3br --price-max 600000 --json

Troubleshooting

Not found errors (exit code 3)

  • Check the resource ID is correct
  • Run the list command to see available items

API-specific

  • homes / region returns HTTP 403 or 429 — Surf cleared the homepage but Redfin rate-limits per IP. Run redfin-pp-cli doctor and wait 30-60 seconds before retrying; cliutil.AdaptiveLimiter will back off automatically.
  • All commands return 403 from non-US IPs — Stingray is geo-restricted to US IPs. Run from a US-based machine, or use a US VPN.
  • watch reports no changes when you know listings changed — Confirm a previous sync-search exists. Check with: sqlite3 ~/.local/share/redfin-pp-cli/data.db "SELECT MAX(observed_at) FROM listing_snapshots WHERE saved_search = 'austin-3br'". If empty, run sync first.
  • rank or summary returns empty — These read from the local store. Run sync-search first. Check with: sqlite3 ~/.local/share/redfin-pp-cli/data.db "SELECT COUNT(*) FROM listing".
  • export hits the 350-row cap on a single price band — The bulk exporter slices the price space automatically. If a band is still saturated, narrow --status or split by --year.
  • JSON parse error: unexpected token at offset 0 — Stingray wraps responses in {}&&{...}. The CLI strips the prefix automatically; if you're calling the API directly, drop the first 4 bytes before parsing.

HTTP Transport

This CLI uses Chrome-compatible HTTP transport for browser-facing endpoints. It does not require a resident browser process for normal API calls.

Discovery Signals

This CLI was generated with browser-captured traffic analysis.

  • Target observed: https://www.redfin.com
  • Capture coverage: 0 API entries from 0 total network entries
  • Reachability: browser_http (70% confidence)
  • Protocols: stingray-json-api (95% confidence)
  • Protection signals: aws-cloudfront-waf (85% confidence)
  • Generation hints: Strip the {}&& CSRF prefix from every Stingray JSON response before decoding, Use Surf with Chrome TLS fingerprint at runtime (UsesBrowserHTTPTransport), Conservative rate limit: 1 req/s default with adaptive backoff on 429, Stingray is geo-restricted to US IPs; doctor command should warn non-US users, Region IDs are visible in redfin.com URL paths (e.g., /city/30772/TX/Austin); region type 6=city, 1=zip, 11=neighborhood
  • Candidate command ideas: homes — Stingray gis search is the primary entry point; listing — Listing detail composes initialInfo + aboveTheFold + belowTheFold; market — aggregate-trends endpoint exposes neighborhood medians

Warnings from discovery:

  • csrf-prefix: Stingray JSON responses are prefixed with the literal bytes '{}&&' as CSRF prevention. Generated client must strip them before json.Unmarshal.
  • geo-restricted: Stingray endpoints are US-only. Non-US callers will get 403 regardless of TLS fingerprint.

Sources & Inspiration

This CLI was built by studying these projects and resources:

Generated by CLI Printing Press

For agents: pass /documentation/redfin/agents.md to install this CLI from a prompt.