1. Where the file is
Two CSV files, no login, updated every day: data.sandiego.gov/datasets/development-permits — approvals_created and approvals_issued. The columns that matter are the address, the approval type and status, the scope, the valuation where the City captured one, and APPROVAL_PERMIT_HOLDER: who the City recorded as the permit holder.
2. What "owner-pulled" means, exactly
The holder field is a name. When it is a company — a contractor, a solar installer, a permit-running service — a licensed business already holds the job. When it is a person, the permit was filed in an individual's name. That is the whole signal, and it is narrower than it sounds. A permit records that a fee was paid and that a field is empty. It does not say whether the owner has already spoken to a contractor. So we say exactly what the record supports — an individual, one property, no contractor named on the permit — and nothing about who they have or have not called.
3. The filter that actually matters
The first version of this feed trusted the name shape, and sold contractors' permits as homeowners': a person-shaped name that appears at 529 different addresses across the year is a company, however it is spelled. So the working rule is one holder, one address: any holder found at more than one distinct property in the year's file is dropped. That removed 60–76% of what looked owner-pulled, and every genuine homeowner in the sample sat at exactly one address. Then keep only Opened / Issued — a permit at Inspection Followup is work already underway.
Do that by hand and it is an 18 MB spreadsheet every Monday. We do it every Monday and email the result by trade.