Pencilwrite Get early access
Pencilwrite / Data API
Free, static, no key

Minnesota Rent Data API

The same numbers behind the MN Rent Explorer, as JSON. Five endpoints, served as static files from the edge, CORS open to any origin, cached for a day. No key, no rate limit, no signup. Licensed CC BY 4.0, so attribution is the only condition.

ZIP endpoints
914
one file per ZIP code
County endpoints
87
one file per county
Schema version
1.0
OpenAPI 3.1 at /openapi.json
Last updated
2026-09-05
newest source import

Endpoints

PathReturns
/api/v1/index.jsonEvery one of the 914 ZIP codes in one array: fair market rent by bedroom, year over year change, latest market rent, spread, and the voucher competitive flag.
/api/v1/zip/{zip}.jsonOne ZIP code in full: the fair market rent series by fiscal year and bedroom count, the monthly market rent series, ACS medians where published, and the six nearest ZIP codes.
/api/v1/county/{slug}.jsonOne of the 87 counties: medians, ZIP count, and a row per ZIP code. Slug is the lowercase county name with non alphanumeric runs collapsed to one hyphen, for example st-louis.
/api/v1/section-8.jsonThe 172 ZIP codes carrying both a fair market rent and a market rent, with the spread in dollars and percent and a summary block.
/api/v1/meta.jsonCounts, source vintages, the license, the citation string, and the endpoint list. Fetch this first to see whether anything changed.

Base URL is https://pencilwrite.com. Every response carries a meta object with the license, the attribution string, source vintages, the generation timestamp, and the schema version. The full machine readable contract is at /openapi.json.

Quick start

curl -s https://pencilwrite.com/api/v1/zip/55401.json | jq '.fmr.br2'

curl -s https://pencilwrite.com/api/v1/section-8.json | jq '.summary'

curl -s https://pencilwrite.com/api/v1/index.json \
  | jq '[.zips[] | select(.voucher_competitive == true)] | length'
# Python
import requests
z = requests.get("https://pencilwrite.com/api/v1/zip/55401.json", timeout=10).json()
print(z["city"], z["fmr"]["br2"], z["meta"]["attribution"])

// JavaScript
const r = await fetch("https://pencilwrite.com/api/v1/section-8.json");
const {summary, rows} = await r.json();
console.log(summary.voucher_competitive_count, rows.length);

Files are immutable between regenerations and served with a one day cache. Poll /api/v1/meta.json and compare generated_at rather than refetching every ZIP.

License and attribution

Published under CC BY 4.0. Commercial use is fine. Cite as: Pencilwrite MN Rent Data, pencilwrite.com/rents/.

Read the methodology before you build on these numbers. Fair market rent is a 40th percentile estimate on a federal fiscal year and the Zillow index is a smoothed asking rent index across all unit sizes. Neither is a rent quote for any address. Underlying sources keep their own terms.

MCP server

An MCP server exposing the same data to agents is coming soon at mcp.pencilwrite.com. Until then, agents can read /llms.txt for the short index or /llms-full.txt for the full plain text summary, or call these endpoints directly. Every payload names its source vintages and carries the attribution string in meta.attribution.

Start free

Underwriting a deal in Minnesota?

Pencilwrite turns an address, a price, and these rents into a full underwrite, cap rate, cash-on-cash, DSCR, true ROE, taxes, and an offer you can send. Limited beta access spots open. Sign up for the beta, opening in the next two months. Free.

See a sample underwrite first