yajra/zillow
Laravel wrapper for the Zillow API, letting you query property data, Zestimates, and listing details through a clean, fluent interface. Integrate real estate info into your PHP apps with minimal setup.
Architecture fit. yajra/zillow follows the canonical Laravel provider-integration shape: a service provider registers a singleton binding, a publishable config file carries the API key, a facade exposes a fluent query surface, and a thin client maps Zillow's legacy XML into objects. For a TPM, the package's value is not its code but its shape — it is a concrete, near-zero-cost artifact that demonstrates exactly where a property-data dependency belongs in our stack (bound service, config/env surface, facade call at the controller or service boundary) and how little plumbing is actually involved. Use it to calibrate estimates and to correct stakeholder intuition that a vendor integration is a workstream; any competent vendor client is a few hundred lines of configuration and response mapping.
Integration feasibility. Composer install is plausible; function is not operable. Zillow retired public access to the legacy endpoints this wrapper targets (GetSearchResults, GetDeepSearchResults, GetZestimate, GetChart), so every call path resolves to a route that no longer exists. Secondary blockers are dependency drift — Laravel 5.x-era illuminate/* pins and Guzzle constraints that will collide with a current composer.json — and the complete absence of a live contract to test against. The framing a TPM must hold steady for stakeholders: this is not an integration decision, it is a data-access and licensing decision the package cannot influence in either direction.
Technical risk. High and structural across three independent axes, any one of which is disqualifying for production:
Key questions.
PropertyData service bound to a live vendor?Stack fit. Nominally yes, substantively no. It matches the Laravel idiom precisely, but "fits the framework" is not "fits the requirement." Dropped into composer.json it would be an inert passenger: no queueing, no caching, no retry or backoff, no circuit-breaking, no observability hooks — and no live upstream to observe anyway. Every resilience property we would need in production is absent and would become our team's work, invisible in the "it's only a few days" estimate.
Migration path. There is no migration to this package; the correct path migrates past it.
PropertyData service bound to a current provider. Do not require the abandoned package under any circumstances.Compatibility. Assume incompatible until proven otherwise. Expect a PHP ^7.x floor, Laravel 5.x-era illuminate/* pins, and Guzzle constraints that conflict with a current stack. Two traps for stakeholders: (a) a successful composer require says nothing about whether the feature works, and (b) a forked patch to satisfy constraints pulls the package permanently into our maintenance surface. Do not report "it installed" as progress.
Sequencing. The order matters more than the decision on this package.
PropertyData interface, adding caching, queueing, error handling, and observability there — not in controllers or models.yajra/zillow in the ADR appendix as an optional design reference. Never on the critical path, never in a sprint plan, never attached to a release-date commitment.Maintenance. Effectively unmaintained. If adopted, we inherit permanent ownership — including the eventual job of reimplementing it against a different vendor, which is strictly worse than writing the small client ourselves from the start. The honest comparison is not "package versus nothing," it is "a package we now own forever versus 200 lines we wrote and understand." Frame it that way in any build-vs-adopt discussion.
Support. Zero. No issue traffic, no Stack Overflow footprint, no downstream dependents to learn from, no upgrade path when a response shape changes. Support burden transfers 100% to our team the moment it enters the dependency graph, and the first incident ("the API returns 410 Gone") is unresolvable by design — no upstream to escalate to, no fix to ship. That is an on-call page with no runbook. State it plainly in the risk register rather than softening it.
Scaling. Moot as a code question, but the planning answer is the one that matters. Rate limits, quotas, throughput guarantees, and SLAs are properties of an upstream that no longer exists. The scaling constraints we should actually budget against live in the vendor contract: request quotas, per-record pricing, caching and persistence rights, whether AVM results may be stored or must be re-fetched, and whether derived data may be redistributed. Pull those terms into the vendor evaluation explicitly — they shape architecture, unit economics, and the user-facing roadmap far more than any wrapper does.
Failure modes. Three distinct classes, all of which land on our team:
Ramp-up. Negligible as a technical matter — the API surface is small and Laravel-idiomatic, and an engineer can read it in an hour. That is precisely why it is a poor use of anyone's ramp-up budget: the time is better spent learning the chosen vendor's contract and building the internal PropertyData abstraction that survives a swap. The one thing worth transferring from this package is the architecture guardrail it embodies and the principle it teaches: every external data dependency sits behind a first-party interface so a vendor change is a config change, not a rewrite. That lesson is reusable regardless of which provider we ultimately select — and it is the only durable asset this evaluation produces.
How can I help you explore Laravel packages today?