DocsMarket context tools

Market context tools

Besides your own data, Ontyx offers a small set of public-data tools for market context: US Census figures by zip code and tract, housing supply and rent benchmarks by county, geocoding, nearby places and maps. They answer from public sources, not from your organization’s data, and every member can use them, readers included.

Not every Ontyx environment offers all of them: the tools your assistant lists are the ones yours has. Where live Census data isn’t turned on, get_population and get_average_income answer from a small built-in sample, and their descriptions say so.

Monthly allowance

Unlike the tools for your own data, these count toward a monthly allowance. Each successful call counts once, and the answer carries a quota field with how much is used (used, limit, percent, state and period; left out of the examples below). Failed calls (a rejected input, an unknown zip, an upstream failure) aren’t counted. When the allowance is used up, these calls can be refused with QUOTA_EXCEEDED until it resets on the 1st of the next month.

Coordinate order. Every coordinate in the location tools is [longitude, latitude] (WGS84, the GeoJSON order): longitude first, in inputs and in the position of every result. get_underwriting_bundle, get_supply_pipeline and get_rent_benchmark take lat and lng as separate fields instead.

Demographic lookups

From the latest US Census American Community Survey (ACS) 5-year estimates. The zip tools resolve a 5-digit zip to its ZIP Code Tabulation Area (ZCTA), the Census geography that approximates a zip, so results carry the ACS geoid, the vintage (acs_year, survey) and a margin of error (moe).

get_population

The resident population of a US zip code.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
zipyesA 5-digit US zip code.

Answers with ok, zip, population, moe, acs_year, survey and geoid. For a zip the ACS has no data for, ok is false and reason is "unknown_zip".

{
  "ok": true,
  "zip": "90210",
  "population": 19004,
  "moe": 1101,
  "acs_year": 2024,
  "survey": "5yr",
  "geoid": "860Z200US90210"
}

get_average_income

The median household income of a US zip code (ACS table B19013). The name is kept for compatibility, but the value is a median, not a mean. A top-coded median (such as 250001) means “that amount or more”.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
zipyesA 5-digit US zip code.

Answers with ok, zip, median_household_income_usd, moe_usd, currency ("USD"), acs_year, survey and geoid, or reason: "unknown_zip".

get_underwriting_bundle

A commercial real estate underwriting snapshot for a US Census tract: about 22 demographic, housing, income and employment figures.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
tract_geoidone of the twoAn 11-digit Census tract geoid.
lat, lngone of the twoA coordinate, resolved to its tract.

Answers with ok, tract_geoid, acs_year, survey and the figures: total_population, total_households, median_household_income_usd, median_gross_rent_usd, median_home_value_usd, median_owner_costs_usd, rent_to_income_ratio, owner_cost_to_income_ratio, total_housing_units, vacancy_rate, five share_built_* era shares, bachelors_share, total_employed, industry_hhi and four transport_*_share commute shares. A figure is null where the ACS doesn’t publish a value.

Market outlook

Two county-level tools for what current demographics can’t say: what supply is coming, and what a fair rent is. Both accept a tract or a coordinate for convenience, but the answer is always for the county: building permits are only complete monthly at county level, and fair-market rents have no smaller form in most of the country. Every answer says so in geography_grain and resolved_from.

get_supply_pipeline

Forward-looking housing supply for a county, from Census building-permit authorizations.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
county_geoidone of the threeA 5-digit state and county geoid.
tract_geoidone of the threeAn 11-digit tract geoid, rolled up to its county.
lat, lngone of the threeA coordinate, resolved to its county.

Answers with geography_grain and resolved_from, and keeps what was observed apart from what’s forecast:

  • observed: arithmetic on authorized permit counts: trailing 12-month units, multifamily share, year-over-year change, the standing pipeline, and permits per 1,000 existing homes.
  • outlook: modelled: expected deliveries over the next 12 months, expected stock growth, and supply_pressure and supply_momentum labels. supply_pressure is relative: elevated means the top fifth of counties nationally for expected stock growth, limited the bottom fifth.
  • assumptions: the permit-to-completion lags and completion rates used for outlook. They’re calibration defaults, not measurements.
  • benchmarks: national and in-state percentile ranks.
  • data_quality: whether the trailing windows are complete, and how much of the count was reported rather than estimated by the survey.

get_rent_benchmark

A standardized fair-market rent for a county, by unit size from studio to four bedrooms.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
county_geoidone of the threeA 5-digit state and county geoid.
tract_geoidone of the threeAn 11-digit tract geoid, rolled up to its county.
lat, lngone of the threeA coordinate, resolved to its county.

Answers with geography_grain, resolved_from, rents, trend (growth with and without inflation), vs_market (against the median rent tenants pay now), affordability (against local incomes and area income limits; empty where income limits aren’t available) and benchmarks. Three things to carry into any answer built on it:

  • Rents are gross: rent plus tenant-paid utilities. They compare with gross-rent survey figures, not contract rent, and aren’t a current asking rent.
  • fmr_percentile (40 or 50) is definitional. An area measured at the 50th percentile isn’t more expensive than one measured at the 40th; it’s measured at a different point of its own range. Don’t rank across the two without saying which is which.
  • fmr_2br_to_acs_median_rent_ratio is a screening ratio that overstates the gap to market, because the survey median it divides by is a five-year average across every unit size.

Location

Geocoding, reverse geocoding, nearby places and static maps. Results with a position (geocode, reverse_geocode, search_nearby) also carry h3, the H3 cell id of that point; h3Resolution (0 to 15, default 9) sets the cell size.

geocode

Turns an address or place name into candidate positions.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
queryyesFree-form address or place text.
maxResultsno1 to 50 (default 5).
biasPositionno[lon, lat] to favour results near.
countryFilternoISO 3166-1 alpha-3 country codes to keep to, such as ["USA"].
h3Resolutionno0 to 15, default 9.

Answers with results, each with label, position, h3 and, where known, relevance, country, region and postalCode.

{
  "results": [
    {
      "label": "Golden Gate Brg, San Francisco, CA 94129, United States",
      "position": [-122.47846, 37.8183],
      "country": "USA",
      "region": "CA",
      "postalCode": "94129",
      "relevance": 1,
      "h3": "89283087037ffff"
    }
  ]
}

reverse_geocode

Turns a position into nearby addresses.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
positionyes[lon, lat].
maxResultsno1 to 50 (default 1).
h3Resolutionno0 to 15, default 9.

Answers with results, each with label, position, h3 and, where known, distanceMeters, country, region and postalCode.

search_nearby

Places around a position, filtered by category. There’s no free-text search: filter with categories.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
positionyes[lon, lat], the centre of the search.
radiusMetersno1 to 50,000 (default 1,000).
maxResultsno1 to 50 (default 10).
categoriesnoAWS Location place category ids to keep to.
h3Resolutionno0 to 15, default 9.

Answers with results, each with placeId, label, position, h3 and, where known, distanceMeters, categories and address.

static_map

Renders a map image.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
framingyesExactly one of { "type": "center", "center": [lon, lat], "zoom": 0-20 }, { "type": "boundingBox", "boundingBox": [west, south, east, north] } or { "type": "boundedPositions", "positions": [[lon, lat], …] } (two or more points).
aspectRationo16:9 (default), 3:2, 4:3, 5:4 or 1:1.
orientationnolandscape (default) or portrait.
qualitynostandard (default) or high (1080p-class, such as 1920×1080 at 16:9).
stylenostandard (road map, default, and the best base under an overlay) or satellite.
geojsonOverlaynoA GeoJSON FeatureCollection to draw, at most 4,200 characters.
poisnoShow built-in place icons (default false).

Answers with an inline preview image and a text block whose first line is a link to the full-resolution JPEG (Full map (JPEG, W×H): <signed url>), then a caption, then { url, expiresAt, width, height, bucketKey }. The link is short-lived; expiresAt says when it stops working. The inline image is left out when the whole answer would be too large (see Answer size); the link always carries the map.

Maps of a metric

map_metric

A map of one Census-tract figure around a place, coloured by value, for when someone wants to see how it varies. For the numbers themselves, use get_underwriting_bundle.

Who can call it: anyone connected, readers included.

InputRequiredWhat it is
locationyesExactly one of { "address": "…" } (its top geocode match is used) or { "position": [lon, lat] }.
metricyesmedian_household_income, median_gross_rent, median_home_value, rent_burden, vacancy_rate, population_density, bachelors_share, share_built_post_2010, transit_share or wfh_share.
radius_kmno1 to 25 (default 5). Every tract touching the circle is drawn.
presetnoreport (muted base map, default) or presentation (higher-contrast labels).
classesnoNumber of colour classes, 3 to 7 (default 5).
palettenoBlues, Greens, Oranges, Purples, Reds or YlGnBu. Default: one chosen per metric.

Answers with a text block whose first line links to the 1080×1080 PNG (Full map (PNG, 1080×1080): <signed url>), then a caption, then the details: url, expiresAt, width, height, legend, metric, label, format, place, center, radius_km, acs_year, breaks (worked out by quantile over the tracts with data), classes, palette, stats (n_tracts, n_with_data, min, max, median), and highest and lowest (the three tracts at each end). An inline 800×800 preview image comes first for clients that show images. Without a map renderer configured, the tool answers with a render_unavailable error.

Answer size

Map tools can return large answers: an 800×800 preview image is about 117,000 characters on its own.

  • Clients that show the interactive map card (MCP Apps hosts) get the text block only. The card loads the full image from the link, so the inline copy isn’t needed, which keeps a map_metric answer under 6,000 characters.
  • Every other client gets the image too, unless the whole answer would pass 120,000 characters. Then the image is dropped, never the link, the caption or the details, and the caption says so.

Errors

These tools answer errors as structured JSON in the tool result. Errors from Ontyx itself use these codes:

  • UNAUTHENTICATED: the sign-in or key was missing, invalid or revoked.
  • RATE_LIMITED: too many requests in a short time; retryAfterMs says how long to wait.
  • QUOTA_EXCEEDED: the monthly allowance is used up (see Monthly allowance).
  • INVALID_REQUEST: the input didn’t fit the tool’s inputs.

Errors from the location and Census services come through as { "error": { "code", "message" } }:

  • invalid_request: parameters the service rejected.
  • unknown_route: the service doesn’t recognize the operation.
  • not_found: no data for that place (the zip tools answer { "reason": "unknown_zip" } instead).
  • upstream_error: the service failed, for example on a coordinate out of range.
  • upstream_timeout: a lookup ran out of time.

None of these failed calls is counted.