The net sheet API

Send a price and an address. Get back what the seller nets or what the buyer brings to closing, line by line, with that county's transfer taxes, title customs, recording fees and prorations.

  • All 50 states and DC, every county, plus city transfer taxes
  • Seller net sheets and buyer cash to close, with conventional, FHA, VA, USDA, jumbo or cash loans
  • The same engine as the NetSheet.org calculator, with each rule's source and the date it was checked
  • 250 free calls a month. Then pay as you go at 1¢ a call, or plans from $29.
Request
curl https://api.netsheet.org/v1/quote \
  -H "Authorization: Bearer $NETSHEET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "seller",
    "state": "FL",
    "county": "Hillsborough",
    "salePrice": 650000,
    "firstMortgage": 280000,
    "commissionRate": 5,
    "closingDate": "2026-11-16"
  }'
Response (shortened)
{
  "object": "net_sheet",
  "type": "seller",
  "headline": { "netProceeds": 322807.87 },
  "lines": [
    { "label": "Real estate commission (5%)", "amount": 32500 },
    { "label": "First mortgage payoff", "amount": 280000 },
    { "label": "Documentary stamp tax on deed", "amount": 4550 },
    { "label": "Owner's title insurance policy", "amount": 3325 },
    …
  ]
}

Pricing

Every plan gets the whole API. You pay for volume: a call is one quote or one address lookup. State, county and rule lookups are free. Pay as you go, take a monthly plan, or both.

Billing

Yearly billing costs the same as 10 months.

Sandbox

For building and testing your integration.

$0 forever

No credit card needed.

250 calls a month10 requests a minute

Get a free key

Starter

For a brokerage tool, a CRM add-on or a small site.

$29 a month

 

5,000 calls a month60 requests a minute. Under 0.6¢ a call.

Scale

For portals and platforms quoting every listing.

$299 a month

 

250,000 calls a month1,000 requests a minute. About 0.12¢ a call.

Pay as you go

1¢ a call

Buy calls in packs. They never expire, and they are only used once your plan's calls for the month run out, so they work on their own or as a top-up on any plan. Holding calls also raises a Sandbox account to 60 requests a minute.

Plans work out cheaper once you make more than about 2,900 calls a month. You are never billed for calls after the fact: when the plan's calls and your prepaid calls are both used up, the API answers 429 until the 1st, until you buy more, or until you move up a plan (that takes effect at once and is prorated). Need more than 250,000 calls a month? Email support@netsheet.org.

Your API keys

API keys belong to a NetSheet.org account. Create a free account or log in, and you can make a Sandbox key here straight away.

Documentation

A JSON API over HTTPS. Base URL: https://api.netsheet.org/v1

Authentication

Send your key in the Authorization header on every request. X-Api-Key: ns_live_… works too.

Header
Authorization: Bearer ns_live_…

Keys begin with ns_live_. Make and revoke them above. A revoked key stops working at once. Call from your server, not from a web page, where anyone could read the key.

Quote a net sheet

POST /v1/quote 1 call

Calculates a seller net sheet (net proceeds) or a buyer net sheet (cash to close). Nothing is saved. Only type, state and salePrice are required. Give the county too, because many states tax differently by county and city. When you only have an address, call resolve-address first. Anything you leave out is estimated from local custom, and the response lists those estimates under assumptions.

FieldTypeMeaning
typerequiredstringseller or buyer
staterequiredstringTwo-letter code, e.g. FL
salePricerequirednumberSale or purchase price in dollars
countystringCounty name without the word County, e.g. Hillsborough
city, zipstringNeeded where a city has its own transfer tax, as Philadelphia and San Francisco do
propertyAddressstringEchoed back for your records
closingDatestringYYYY-MM-DD. Needed for the property tax proration and the buyer's prepaid interest. Without it, neither is calculated
propertyTypestringsingle-family, condo, townhome, multi-family, land or commercial
commissionRatenumberTotal commission percent. Default 6
firstMortgage, secondMortgage, helocPayoffnumberSeller loan payoffs
annualPropertyTaxnumberThe actual annual tax bill, when known
hoaMonthlyDuesnumberMonthly HOA dues
sellerCredits, repairs, homeWarrantynumberSeller-paid concessions and costs
loanTypestringBuyer financing: conventional, fha, va, usda, jumbo or cash
downPaymentPercent, loanAmountnumberBuyer down payment, or the loan amount
interestRatenumberAnnual percent, for prepaid interest. Default 6.5
earnestMoneynumberBuyer's deposit, credited at closing
customFeesarray[{ "name": "Courier", "amount": 75, "payer": "seller" }]

Money accepts numbers or strings such as "$150,000". The response has the headline figure (netProceeds for sellers, cashToClose and loanAmount for buyers), the totals for that side, every non-zero line with its group, the assumptions made, any warnings, and the rulesVersion it was calculated with.

A buyer quote in JavaScript
const res = await fetch('https://api.netsheet.org/v1/quote', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NETSHEET_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    type: 'buyer', state: 'TX', county: 'Travis', salePrice: 400000,
    loanType: 'conventional', downPaymentPercent: 20, interestRate: 6.5
  })
});
const sheet = await res.json();
console.log(sheet.headline); // { cashToClose: …, loanAmount: 320000 }
The same in Python
import os, requests

sheet = requests.post(
    "https://api.netsheet.org/v1/quote",
    headers={"Authorization": f"Bearer {os.environ['NETSHEET_KEY']}"},
    json={"type": "buyer", "state": "TX", "county": "Travis", "salePrice": 400000,
          "loanType": "conventional", "downPaymentPercent": 20, "interestRate": 6.5},
    timeout=30,
).json()
print(sheet["headline"])

Resolve an address

POST /v1/resolve-address 1 call

Finds the state, county, city and ZIP for a street address, a ZIP code or "City, ST", with that place's closing customs: who customarily pays for the owner's title policy, the usual settlement fee, whether an attorney is required, and the typical property tax rate. Send address, and state or zip when you have them.

Request and response (shortened)
curl https://api.netsheet.org/v1/resolve-address \
  -H "Authorization: Bearer $NETSHEET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "address": "3415 S Virginia Ct, Tampa, FL 33629" }'

{ "jurisdiction": { "state": "FL", "county": "Hillsborough", "city": "Tampa", "zip": "33629", … },
  "customs": { "ownerTitlePolicy": "seller", "attorneyRequired": false, … } }

A place that cannot be found answers 404 and is not counted.

States, counties and rules

GET /v1/states free

GET /v1/states/{state}/counties free

GET /v1/states/{state}/rules free

The supported states, a state's counties (with FIPS codes and a flag for counties with rules of their own), and a state's rules: each transfer and mortgage tax with its rate, who customarily pays, where it applies, its source and when it was last checked, plus title, recording and county customs. Good for building your own forms and showing your users where a figure came from.

Usage

GET /v1/usage free

Your plan, the plan's calls used this month, calls left, when the count resets, and your prepaid credits. The same numbers come back on every metered call in the X-Quota-Limit, X-Quota-Remaining, X-Quota-Reset and X-Credits-Remaining headers.

Limits

Each plan has a monthly allowance of calls and a per-minute rate (see Pricing). Once the allowance is used, metered calls come out of your prepaid calls, if you have any. The rate applies to every request, free ones too. Address lookups are also held to 60 a minute on every plan. The count resets at midnight UTC on the 1st of the month. Rate headers follow the IETF RateLimit draft, and a 429 carries Retry-After.

Errors

Errors return a status code and a body like { "error": { "type": "invalid_request", "message": "…" } }. The message says what to fix. A request that fails is not counted.

TypeStatusWhen
invalid_request400A field is missing or cannot be read
authentication_required401No key was sent
invalid_key401The key is wrong or was revoked
not_found404No such endpoint, state or place
rate_limited429Too many requests this minute. Wait for Retry-After
quota_exceeded429This month's plan calls and your prepaid calls are both used up
server_error, unavailable5xxOur side. Retry with a short backoff

Figures are estimates for planning, not a Closing Disclosure. Show your users that title, escrow or the lender confirms the final numbers.

Questions

What counts as a call?

One quote or one address lookup that succeeds. Requests that fail, and lookups of states, counties, rules and your usage, are not counted.

What happens when I run out?

Your prepaid calls are used next, if you have any. When those are gone too, metered requests answer 429 quota_exceeded until the 1st of the month. You are never billed for extra calls after the fact. Buying calls or moving up a plan takes effect at once; a plan change is prorated.

Where do the rates come from, and how current are they?

Each rule is taken from the state or county's own statute, fee schedule or rate filing, and records its source and the date it was last checked. You can read them all through /v1/states/{state}/rules. Every quote carries the rulesVersion it used, so you can tell when a figure changed because a rule did.

Can I show the numbers on my own site or app?

Yes, that is what the API is for. Present them as estimates, and make the calls from your server so the key stays private.

Do prepaid calls expire?

No. They stay on your account until you use them, including if you cancel a plan. A refunded pack takes back whichever of its calls are still unused.

How do I cancel?

Open Billing and invoices in your API keys. A cancelled plan runs to the end of the period you paid for, then the account goes back to Sandbox. Your keys keep working on the Sandbox allowance.

Is this the same as the NetSheet.org app plans?

No. Professional and Agency are for agents using the app. API plans are billed on their own, and one account can have both.