AgencyGraph REST API
Base URL https://platform.casafari.com/v1/agencygraph; the country is in the path (/v1/agencygraph/es/..., /v1/agencygraph/pt/...). Send Authorization: Bearer $CASAFARI_API_KEY: a platform API key or an OAuth access token (platform API keys). Each call costs tokens (1 token = EUR 0.04); lists return pages of up to 25 rows (size, offset; the answer's next_offset is the next page's offset, or null after the last), and each page is a call. Only a 2xx answer is billed. Location ids come from Location Lookup (GET /v1/locations/search, free). The MCP tools give the same JSON.
Errors are problem+json with a request_id: 400 invalid_request (malformed input, a country that is not available yet, more than 25 agency_ids, a city dataset bought at another tier than the town's), 400 page_depth_exceeded (past the benchmark's first 100 agencies), 401, 402 (out of tokens), 403 not_entitled, 404 not_found (an unknown agency, town, network or dataset), 502 upstream_error; none of them is billed.
Every example is illustrative: made-up agencies, ids and figures, not real data.
| Operation | What it does | Tokens | MCP tool |
|---|---|---|---|
GET /v1/agencygraph/coverage | Countries answered and their latest weekly build | Free | agencygraph_coverage |
GET /v1/agencygraph/{country}/coverage | One country's towns and agencies in detail | 5 tokens per call | agencygraph_country_coverage |
GET /v1/agencygraph/{country}/agencies | Find an agency by name, trading name or website | Free | agencygraph_resolve_agency |
GET /v1/agencygraph/{country}/agencies/{agency_id} | One agency: towns, five measures, quarters | 50 tokens per call | agencygraph_agency_profile |
GET /v1/agencygraph/{country}/benchmark | Agencies of a town with the five measures | 75 tokens per page of up to 25 rows (the first 100 agencies of a town) | agencygraph_area_benchmark |
GET /v1/agencygraph/{country}/market-share | Agencies' shares of a town's stock and flow | 50 tokens per page of up to 25 rows | agencygraph_market_share |
GET /v1/agencygraph/{country}/agencies/{agency_id}/territory | The towns where an agency works | 50 tokens per page of up to 25 rows | agencygraph_territory |
GET /v1/agencygraph/{country}/networks/{brand} | A franchise network and its offices | 75 tokens per page of up to 25 rows | agencygraph_network |
POST /v1/agencygraph/{country}/screen | Screen agencies by ranges of the measures | 100 tokens per page of up to 25 rows | agencygraph_screen_agencies |
GET /v1/agencygraph/{country}/changes | What changed for up to 25 agencies since a date | 25 tokens per call (up to 25 agencies) | agencygraph_changes |
GET /v1/agencygraph/{country}/datasets | A town's city dataset tier and price | Free | REST only |
POST /v1/agencygraph/{country}/datasets/small | Buy the city dataset of a small city or district | 2,500 tokens per call | REST only |
POST /v1/agencygraph/{country}/datasets/mid | Buy the city dataset of a mid-size city | 6,250 tokens per call | REST only |
POST /v1/agencygraph/{country}/datasets/large | Buy the city dataset of a large city | 12,500 tokens per call | REST only |
GET /v1/agencygraph/{country}/datasets/{dataset_id} | Download a bought city dataset (JSON or CSV) | Free | REST only |
Countries answered and their latest weekly build
GET /v1/agencygraph/coverage · Free · over MCP: agencygraph_coverage
Lists the countries AgencyGraph answers for, with the date of each country's latest weekly build and the property type groups it measures, and the countries not yet available.
Example request
curl "https://platform.casafari.com/v1/agencygraph/coverage" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"countries": [
{
"country": "ES",
"name": "Spain",
"as_of": "2026-10-26",
"type_groups": [
"all",
"apartment",
"house"
],
"operations": [
"sale"
]
},
{
"country": "PT",
"name": "Portugal",
"as_of": "2026-10-26",
"type_groups": [
"all",
"apartment",
"house"
],
"operations": [
"sale"
]
}
],
"not_yet_available": [
{
"country": "IT",
"name": "Italy"
},
{
"country": "DE",
"name": "Germany"
}
],
"method_url": "https://developers.casafari.com/docs/agencygraph"
}One country's towns and agencies in detail
GET /v1/agencygraph/{country}/coverage · 5 tokens per call · over MCP: agencygraph_country_coverage
One country's latest weekly build in detail: the towns and agencies measured, their properties, and the 25 towns with the most agencies, each with the size tier of its city dataset.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/coverage" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"name": "Portugal",
"type_groups": [
"all",
"apartment",
"house"
],
"operations": [
"sale"
],
"totals": {
"towns": 300,
"agencies": 9000,
"properties": 150000
},
"towns": [
{
"location_id": 101,
"name": "Lisboa",
"agencies": 2100,
"properties": 26000,
"dataset_tier": "large"
},
{
"location_id": 102,
"name": "Cascais",
"agencies": 650,
"properties": 7400,
"dataset_tier": "mid"
}
]
}Find an agency by name, trading name or website
GET /v1/agencygraph/{country}/agencies · Free · over MCP: agencygraph_resolve_agency
Turns an agency's name, one of its trading names or its website into ranked candidates in one country: agency_id, name, kind (agency, office of a network, network), network, its properties and main towns, and how it matched. Ambiguous names return several candidates and say so. Use the agency_id in the other tools.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).q(string, required): Query parameter. An agency's name, one of its trading names, or its website (domain). 2–100 characters.location_id(integer, optional): Query parameter. Optional: only agencies active in this town: a town or city's location id from locations_search. ≥ 1.
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/agencies?q=Sample%20Homes" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"query": "Sample Homes",
"ambiguous": true,
"results": [
{
"agency_id": "agc_EXAMPLEHOMES00000000000000",
"name": "Sample Homes Lisboa",
"kind": "agency",
"network": null,
"matched_by": "name_contains",
"properties": 214,
"main_towns": [
{
"location_id": 101,
"name": "Lisboa",
"properties": 180
},
{
"location_id": 102,
"name": "Cascais",
"properties": 34
}
]
},
{
"agency_id": "agc_EXAMPLEPORTO00000000000000",
"name": "Sample Homes Porto",
"kind": "office",
"network": "Example Network",
"matched_by": "name_contains",
"properties": 95,
"main_towns": [
{
"location_id": 103,
"name": "Porto",
"properties": 95
}
]
}
]
}One agency: towns, five measures, quarters
GET /v1/agencygraph/{country}/agencies/{agency_id} · 50 tokens per call · over MCP: agencygraph_agency_profile
A merged agency_id answers 200 with the agency it now belongs to and merged_from naming the id you sent.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).agency_id(string, required): Path parameter.operation(string, optional): Query parameter. sale (default): homes for sale. Rentals are not measured yet. Values:sale. default "sale".
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/agencies/agc_EXAMPLEHOMES00000000000000" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"agency": {
"agency_id": "agc_EXAMPLEHOMES00000000000000",
"name": "Sample Homes Lisboa",
"kind": "agency",
"network": null,
"trading_names": [
"Sample Homes Lisboa",
"Sample Homes"
],
"websites": [
"samplehomes.example"
]
},
"totals": {
"towns": 2,
"properties": 214,
"portfolio_value_eur": 158500000
},
"growth": {
"quarter": "2026-Q3",
"new": 79,
"delisted": 15,
"new_change_pct": {
"previous_quarter": 6.7,
"year_before": 10.4
},
"delisted_change_pct": {
"previous_quarter": -11.8,
"year_before": null
}
},
"quarters": [
{
"quarter": "2026-Q3",
"new": 79,
"delisted": 15
},
{
"quarter": "2026-Q2",
"new": 74,
"delisted": 17
},
{
"quarter": "2026-Q1",
"new": 66,
"delisted": 12
},
{
"quarter": "2025-Q4",
"new": 58,
"delisted": 14
}
],
"towns": [
{
"location_id": 101,
"name": "Lisboa",
"measures": [
{
"type_group": "all",
"properties": 180,
"co_listed": 32,
"share": 0.039,
"portfolio": {
"value_eur": 117000000,
"mean_eur": 650000,
"median_eur": 560000,
"min_eur": 173600,
"max_eur": 2688000,
"p25_eur": 403200,
"p75_eur": 789600,
"price_per_sqm_median_eur": 4746
},
"price_changes": {
"cut": 22,
"raised": 3,
"cut_share": 0.12,
"cut_median_pct": -4.8,
"raised_median_pct": 3
},
"overpricing_at_start": {
"median_gap_pct": 7.2,
"share_over_10_pct": 0.24,
"cut_since_share": 0.41
},
"time_on_market": {
"properties_counted": 180,
"days_min": 3,
"days_max": 384,
"days_median": 96,
"days_mean": 120
},
"ranks": {
"portfolio_value": {
"rank": 2,
"of": 486,
"percentile": 99.6
},
"days_on_market": {
"rank": 42,
"of": 486,
"percentile": 91.4
}
}
}
]
}
],
"towns_total": 2
}Agencies of a town with the five measures
GET /v1/agencygraph/{country}/benchmark · 75 tokens per page of up to 25 rows (the first 100 agencies of a town) · over MCP: agencygraph_area_benchmark
At most the first 100 agencies of a town in the chosen order (offset + size <= 100); every agency of a town is the city dataset. Figures under 5 properties are null with their count. Growth is new and delisted homes in the latest complete quarter, with the change on the quarter before and a year before.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).size(integer, optional): Query parameter. Page size, at most 25 (a Free plan account is capped lower). 1–25.offset(integer, optional): Query parameter. Position of the next page, copied from the previous response.location_id(integer, required): Query parameter. The town: a town or city's location id from locations_search. ≥ 1.type_group(string, optional): Query parameter. Property type group: all (default), apartment or house. Values:all,apartment,house. default "all".operation(string, optional): Query parameter. sale (default): homes for sale. Rentals are not measured yet. Values:sale. default "sale".sort(string, optional): Query parameter. The measure to sort by. Values:portfolio_value,properties,share,median_price,price_per_sqm,price_cut_share,days_on_market,overpricing. default "portfolio_value".order(string, optional): Query parameter. asc or desc; default the measure's natural order (fewest days on the market first, the rest largest first). Values:asc,desc.min_properties(integer, optional): Query parameter. Leave out agencies with fewer properties (default 5; below 5 the figures are null). ≥ 1; default 5.
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/benchmark?size=2&location_id=101&sort=portfolio_value" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"location": {
"location_id": 101,
"name": "Lisboa"
},
"type_group": "all",
"sort": "portfolio_value",
"order": "desc",
"total": 100,
"offset": 0,
"size": 2,
"next_offset": 2,
"agencies_in_town": 486,
"results": [
{
"position": 1,
"agency": {
"agency_id": "agc_EXAMPLEPRIME00000000000000",
"name": "Example Prime Estates",
"kind": "office",
"network": "Example Network"
},
"measures": {
"type_group": "all",
"properties": 260,
"co_listed": 47,
"share": 0.0563,
"portfolio": {
"value_eur": 214000000,
"mean_eur": 823077,
"median_eur": 690000,
"min_eur": 213900,
"max_eur": 3312000,
"p25_eur": 496800,
"p75_eur": 972900,
"price_per_sqm_median_eur": 5847
},
"price_changes": {
"cut": 31,
"raised": 5,
"cut_share": 0.12,
"cut_median_pct": -5.5,
"raised_median_pct": 3
},
"overpricing_at_start": {
"median_gap_pct": 9.1,
"share_over_10_pct": 0.3,
"cut_since_share": 0.41
},
"time_on_market": {
"properties_counted": 260,
"days_min": 3,
"days_max": 472,
"days_median": 118,
"days_mean": 148
},
"ranks": {
"portfolio_value": {
"rank": 1,
"of": 486,
"percentile": 99.8
},
"days_on_market": {
"rank": 41,
"of": 486,
"percentile": 91.6
}
}
},
"growth": {
"quarter": "2026-Q3",
"new": 71,
"delisted": 19,
"new_change_pct": {
"previous_quarter": 4.4,
"year_before": 7
},
"delisted_change_pct": {
"previous_quarter": 2.1,
"year_before": -5
}
}
},
{
"position": 2,
"agency": {
"agency_id": "agc_EXAMPLEHOMES00000000000000",
"name": "Sample Homes Lisboa",
"kind": "agency",
"network": null
},
"measures": {
"type_group": "all",
"properties": 180,
"co_listed": 32,
"share": 0.039,
"portfolio": {
"value_eur": 117000000,
"mean_eur": 650000,
"median_eur": 560000,
"min_eur": 173600,
"max_eur": 2688000,
"p25_eur": 403200,
"p75_eur": 789600,
"price_per_sqm_median_eur": 4746
},
"price_changes": {
"cut": 22,
"raised": 3,
"cut_share": 0.12,
"cut_median_pct": -4.8,
"raised_median_pct": 3
},
"overpricing_at_start": {
"median_gap_pct": 7.2,
"share_over_10_pct": 0.24,
"cut_since_share": 0.41
},
"time_on_market": {
"properties_counted": 180,
"days_min": 3,
"days_max": 384,
"days_median": 96,
"days_mean": 120
},
"ranks": {
"portfolio_value": {
"rank": 2,
"of": 486,
"percentile": 99.6
},
"days_on_market": {
"rank": 42,
"of": 486,
"percentile": 91.4
}
}
},
"growth": {
"quarter": "2026-Q3",
"new": 64,
"delisted": 12,
"new_change_pct": {
"previous_quarter": 6.7,
"year_before": 10.7
},
"delisted_change_pct": {
"previous_quarter": -14.3,
"year_before": null
}
}
}
],
"more": "This town has 486 agencies; the benchmark shows the first 100 in this order. Every agency of the town is the city dataset (GET /v1/agencygraph/pt/datasets?location_id=101)."
}Agencies' shares of a town's stock and flow
GET /v1/agencygraph/{country}/market-share · 50 tokens per page of up to 25 rows · over MCP: agencygraph_market_share
Each agency's share of the properties on the market in one town, and of the town's new and delisted homes in the latest complete quarter and the quarter before, largest share first. A home two agencies advertise counts for each, so shares can add up to more than 1. Pages of up to 25 agencies.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).size(integer, optional): Query parameter. Page size, at most 25 (a Free plan account is capped lower). 1–25.offset(integer, optional): Query parameter. Position of the next page, copied from the previous response.location_id(integer, required): Query parameter. The town: a town or city's location id from locations_search. ≥ 1.type_group(string, optional): Query parameter. Property type group: all (default), apartment or house. Values:all,apartment,house. default "all".operation(string, optional): Query parameter. sale (default): homes for sale. Rentals are not measured yet. Values:sale. default "sale".
Example request
curl "https://platform.casafari.com/v1/agencygraph/es/market-share?size=2&location_id=301" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "ES",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"location": {
"location_id": 301,
"name": "Madrid"
},
"type_group": "all",
"quarter": "2026-Q3",
"town_totals": {
"quarter": "2026-Q3",
"new": 9100,
"delisted": 4300,
"previous_quarter": {
"quarter": "2026-Q2",
"new": 8800,
"delisted": 4100
}
},
"total": 2380,
"offset": 0,
"size": 2,
"next_offset": 2,
"results": [
{
"position": 1,
"agency": {
"agency_id": "agc_EXAMPLECENTRO0000000000000",
"name": "Example Inmobiliaria Centro",
"kind": "agency",
"network": null
},
"properties": 310,
"share": 0.034,
"new": 355,
"new_share": 0.039,
"delisted": 133,
"delisted_share": 0.0309,
"previous_quarter": {
"new_share": 0.034,
"delisted_share": 0.0293
}
},
{
"position": 2,
"agency": {
"agency_id": "agc_EXAMPLEMADRID0000000000000",
"name": "Sample Realty Madrid",
"kind": "office",
"network": "Example Network"
},
"properties": 240,
"share": 0.028,
"new": 200,
"new_share": 0.022,
"delisted": 112,
"delisted_share": 0.026,
"previous_quarter": {
"new_share": 0.025,
"delisted_share": 0.0244
}
}
]
}The towns where an agency works
GET /v1/agencygraph/{country}/agencies/{agency_id}/territory · 50 tokens per page of up to 25 rows · over MCP: agencygraph_territory
One row per town where an agency has homes on the market: properties, its share of the town, portfolio value and its rank there, and new and delisted homes of the latest complete quarter. Largest first, pages of up to 25 towns.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).agency_id(string, required): Path parameter.size(integer, optional): Query parameter. Page size, at most 25 (a Free plan account is capped lower). 1–25.offset(integer, optional): Query parameter. Position of the next page, copied from the previous response.type_group(string, optional): Query parameter. Property type group: all (default), apartment or house. Values:all,apartment,house. default "all".operation(string, optional): Query parameter. sale (default): homes for sale. Rentals are not measured yet. Values:sale. default "sale".
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/agencies/agc_EXAMPLEHOMES00000000000000/territory" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"agency": {
"agency_id": "agc_EXAMPLEHOMES00000000000000",
"name": "Sample Homes Lisboa",
"kind": "agency",
"network": null
},
"type_group": "all",
"total": 2,
"offset": 0,
"size": 25,
"next_offset": null,
"results": [
{
"location_id": 101,
"name": "Lisboa",
"properties": 180,
"share": 0.023,
"portfolio_value_eur": 117000000,
"portfolio_value_rank": {
"rank": 2,
"of": 486,
"percentile": 99.6
},
"growth": {
"quarter": "2026-Q3",
"new": 64,
"delisted": 12,
"new_change_pct": {
"previous_quarter": 6.7,
"year_before": 10.7
},
"delisted_change_pct": {
"previous_quarter": null,
"year_before": null
}
}
},
{
"location_id": 102,
"name": "Cascais",
"properties": 34,
"share": 0.019,
"portfolio_value_eur": 41500000,
"portfolio_value_rank": {
"rank": 9,
"of": 122,
"percentile": 92.6
},
"growth": {
"quarter": "2026-Q3",
"new": 15,
"delisted": 3,
"new_change_pct": {
"previous_quarter": 7.1,
"year_before": null
},
"delisted_change_pct": {
"previous_quarter": null,
"year_before": null
}
}
}
]
}A franchise network and its offices
GET /v1/agencygraph/{country}/networks/{brand} · 75 tokens per page of up to 25 rows · over MCP: agencygraph_network
One franchise or brand network in a country (brand, such as agencygraph_resolve_agency returns in network): its totals, and its offices with each one's properties, portfolio value, number of towns and main towns, largest first. location_id narrows it to one town. Pages of up to 25 offices.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).brand(string, required): Path parameter.size(integer, optional): Query parameter. Page size, at most 25 (a Free plan account is capped lower). 1–25.offset(integer, optional): Query parameter. Position of the next page, copied from the previous response.location_id(integer, optional): Query parameter. Optional: only its offices in this town: a town or city's location id from locations_search. ≥ 1.
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/networks/Example%20Network?size=1" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"network": "Example Network",
"totals": {
"offices": 58,
"towns": 74,
"properties": 4120,
"portfolio_value_eur": 1630000000
},
"total": 58,
"offset": 0,
"size": 1,
"next_offset": 1,
"results": [
{
"office": {
"agency_id": "agc_EXAMPLEPRIME00000000000000",
"name": "Example Prime Estates",
"kind": "office",
"network": "Example Network"
},
"properties": 294,
"portfolio_value_eur": 255500000,
"towns": 2,
"main_towns": [
{
"location_id": 101,
"name": "Lisboa",
"properties": 260
},
{
"location_id": 102,
"name": "Cascais",
"properties": 34
}
]
}
]
}Screen agencies by ranges of the measures
POST /v1/agencygraph/{country}/screen · 100 tokens per page of up to 25 rows · over MCP: agencygraph_screen_agencies
Filters agencies, one row per agency and town, in the whole country or in up to 20 towns, by ranges of the measures (portfolio value, share, price cut share, days on the market, overpricing), size, network or independence and property type, sorted as you ask, with each row's measures and growth. For recruitment, partners or agencies growing in an area. Pages of up to 25 rows.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).
Request body
location_ids(integer[], optional): Optional: up to 20 towns (location ids from locations_search); without, the whole country. at most 20 items; ≥ 1.type_group(string, optional): Property type group: all (default), apartment or house. Values:all,apartment,house. default "all".operation(string, optional): sale (default): homes for sale. Rentals are not measured yet. Values:sale. default "sale".sort(string, optional): The measure to sort by. Values:portfolio_value,properties,share,median_price,price_per_sqm,price_cut_share,days_on_market,overpricing. default "portfolio_value".order(string, optional): asc or desc; default the measure's natural order (fewest days on the market first, the rest largest first). Values:asc,desc.min_properties(integer, optional): Leave out agencies with fewer properties (default 5; below 5 the figures are null). ≥ 1; default 5.max_properties(integer, optional): At most this many properties in the town. ≥ 1.min_portfolio_value_eur(number, optional): At least this portfolio value (EUR).max_portfolio_value_eur(number, optional): At most this portfolio value (EUR).min_share(number, optional): At least this share.max_share(number, optional): At most this share.min_price_cut_share(number, optional): At least this price cut share.max_price_cut_share(number, optional): At most this price cut share.min_days_on_market(number, optional): At least this days on market.max_days_on_market(number, optional): At most this days on market.min_overpricing_pct(number, optional): At least this overpricing (percent).max_overpricing_pct(number, optional): At most this overpricing (percent).independent(boolean, optional): true: only agencies that belong to no network.network(string, optional): Only offices of this network. at most 100 characters.size(integer, optional): Rows per page, 1 to 25 (default 25). 1–25; default 25.offset(integer, optional): Rows to skip: the next_offset of the previous page. ≥ 0; default 0.
Example request
curl -X POST "https://platform.casafari.com/v1/agencygraph/pt/screen" \
-H "Authorization: Bearer $CASAFARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"location_ids":[401,402],"independent":true,"min_properties":20,"max_days_on_market":120}'Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"type_group": "all",
"sort": "portfolio_value",
"order": "desc",
"total": 7,
"offset": 0,
"size": 25,
"next_offset": null,
"results": [
{
"agency": {
"agency_id": "agc_EXAMPLENORTE00000000000000",
"name": "Sample Imobiliária Norte",
"kind": "agency",
"network": null
},
"location": {
"location_id": 401,
"name": "Sample Municipality A"
},
"measures": {
"type_group": "all",
"properties": 48,
"co_listed": 9,
"share": 0.0828,
"portfolio": {
"value_eur": 13900000,
"mean_eur": 289583,
"median_eur": 260000,
"min_eur": 80600,
"max_eur": 1248000,
"p25_eur": 187200,
"p75_eur": 366600,
"price_per_sqm_median_eur": 2203
},
"price_changes": {
"cut": 5,
"raised": 1,
"cut_share": 0.1,
"cut_median_pct": -3.9,
"raised_median_pct": 3
},
"overpricing_at_start": {
"median_gap_pct": 5.4,
"share_over_10_pct": 0.18,
"cut_since_share": 0.41
},
"time_on_market": {
"properties_counted": 48,
"days_min": 3,
"days_max": 328,
"days_median": 82,
"days_mean": 102
},
"ranks": {
"portfolio_value": {
"rank": 3,
"of": 61,
"percentile": 95.1
},
"days_on_market": {
"rank": 43,
"of": 61,
"percentile": 29.5
}
}
},
"growth": {
"quarter": "2026-Q3",
"new": 22,
"delisted": 4,
"new_change_pct": {
"previous_quarter": 18,
"year_before": 29.4
},
"delisted_change_pct": {
"previous_quarter": null,
"year_before": null
}
}
}
]
}What changed for up to 25 agencies since a date
GET /v1/agencygraph/{country}/changes · 25 tokens per call (up to 25 agencies) · over MCP: agencygraph_changes
For up to 25 agency_ids, week by week since a date: new, delisted and relisted homes, price increases and cuts with their median change, and merges into another agency. Keep your own list of agency_ids and call it each week to follow them.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).agency_ids(string, required): Query parameter. Up to 25 agency ids to follow (on REST, comma-separated).since(string, optional): Query parameter. A date within the last year, YYYY-MM-DD (default: a week before the latest weekly build). pattern^\d{4}-\d{2}-\d{2}$.
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/changes?agency_ids=agc_EXAMPLEPRIME00000000000000,agc_EXAMPLEOEIRAS0000000000000&since=2026-10-19" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"since": "2026-10-19",
"from_week": "2026-W43",
"results": [
{
"agency_id": "agc_EXAMPLEPRIME00000000000000",
"found": true,
"agency": {
"agency_id": "agc_EXAMPLEPRIME00000000000000",
"name": "Example Prime Estates",
"kind": "office",
"network": "Example Network"
},
"totals": {
"new": 8,
"delisted": 1,
"relisted": 0,
"price_up": 0,
"price_down": 2
},
"weeks": [
{
"week": "2026-W43",
"new": 8,
"delisted": 1,
"relisted": 0,
"price_up": 0,
"price_up_median_pct": null,
"price_down": 2,
"price_down_median_pct": -4.5
}
],
"merges": []
},
{
"agency_id": "agc_EXAMPLEOEIRAS0000000000000",
"found": true,
"agency": {
"agency_id": "agc_EXAMPLEOEIRAS0000000000000",
"name": "Example Casas Oeiras",
"kind": "agency",
"network": null
},
"totals": {
"new": 2,
"delisted": 0,
"relisted": 1,
"price_up": 0,
"price_down": 11
},
"weeks": [
{
"week": "2026-W43",
"new": 2,
"delisted": 0,
"relisted": 1,
"price_up": 0,
"price_up_median_pct": null,
"price_down": 11,
"price_down_median_pct": -6
}
],
"merges": []
}
]
}A town's city dataset tier and price
GET /v1/agencygraph/{country}/datasets · Free · REST only
The tier follows the number of agencies measured in the town (large from 2,000, mid-size from 400, small below); buy with POST to datasets/{tier}.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).location_id(integer, required): Query parameter. The town: a town or city's location id from locations_search. ≥ 1.
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/datasets?location_id=102" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"location": {
"location_id": 102,
"name": "Cascais"
},
"agencies": 650,
"tier": "mid",
"tokens": 6250,
"buy": {
"method": "POST",
"path": "/v1/agencygraph/pt/datasets/mid",
"body": {
"location_id": 102
}
},
"valid_days": 365,
"type_groups": [
"all",
"apartment",
"house"
]
}Buy the city dataset of a small city or district
POST /v1/agencygraph/{country}/datasets/small · 2,500 tokens per call · REST only
Body {location_id}. A town of another tier answers 400 naming its tier, not billed. The answer's dataset_id opens the dataset, rebuilt from the newest weekly build, for one year, for this organisation only.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).
Request body
location_id(integer, required): The town, whose tier must be small: a town or city's location id from locations_search. ≥ 1.
Example request
curl -X POST "https://platform.casafari.com/v1/agencygraph/pt/datasets/small" \
-H "Authorization: Bearer $CASAFARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"location_id":401}'Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"dataset_id": "ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"location": {
"location_id": 401,
"name": "Sample Municipality A"
},
"tier": "small",
"agencies": 120,
"valid_until": "2027-10-30",
"download": {
"json": "/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"csv": "/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000?format=csv"
}
}Buy the city dataset of a mid-size city
POST /v1/agencygraph/{country}/datasets/mid · 6,250 tokens per call · REST only
Body {location_id}. A town of another tier answers 400 naming its tier, not billed. The answer's dataset_id opens the dataset, rebuilt from the newest weekly build, for one year, for this organisation only.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).
Request body
location_id(integer, required): The town, whose tier must be mid: a town or city's location id from locations_search. ≥ 1.
Example request
curl -X POST "https://platform.casafari.com/v1/agencygraph/pt/datasets/mid" \
-H "Authorization: Bearer $CASAFARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"location_id":102}'Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"dataset_id": "ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"location": {
"location_id": 102,
"name": "Cascais"
},
"tier": "mid",
"agencies": 650,
"valid_until": "2027-10-30",
"download": {
"json": "/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"csv": "/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000?format=csv"
}
}Buy the city dataset of a large city
POST /v1/agencygraph/{country}/datasets/large · 12,500 tokens per call · REST only
Body {location_id}. A town of another tier answers 400 naming its tier, not billed. The answer's dataset_id opens the dataset, rebuilt from the newest weekly build, for one year, for this organisation only.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).
Request body
location_id(integer, required): The town, whose tier must be large: a town or city's location id from locations_search. ≥ 1.
Example request
curl -X POST "https://platform.casafari.com/v1/agencygraph/pt/datasets/large" \
-H "Authorization: Bearer $CASAFARI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"location_id":101}'Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"dataset_id": "ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"location": {
"location_id": 101,
"name": "Lisboa"
},
"tier": "large",
"agencies": 2100,
"valid_until": "2027-10-30",
"download": {
"json": "/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"csv": "/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000?format=csv"
}
}Download a bought city dataset (JSON or CSV)
GET /v1/agencygraph/{country}/datasets/{dataset_id} · Free · REST only
Every agency of the town, one row per agency and type group (all, apartment, house): the five measures and new and delisted homes for the last four complete quarters. format=csv answers a CSV file.
Parameters
country(string, required): Path parameter. Country, as in every AgencyGraph path: ES or PT (lower case works too).dataset_id(string, required): Path parameter.format(string, optional): Query parameter. json (default) or csv. Values:json,csv. default "json".
Example request
curl "https://platform.casafari.com/v1/agencygraph/pt/datasets/ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000" \
-H "Authorization: Bearer $CASAFARI_API_KEY"Example response (200)
Illustrative example: made-up agencies, ids and figures, not real data.
{
"country": "PT",
"build": {
"build_id": "agb_EXAMPLEBUILD0000000000001",
"as_of": "2026-10-26"
},
"method_url": "https://developers.casafari.com/docs/agencygraph",
"dataset_id": "ags_RXhhbXBsZURhdGFzZXQ.EXAMPLESIGNATURE00000000",
"location": {
"location_id": 102,
"name": "Cascais"
},
"tier": "mid",
"valid_until": "2027-10-30",
"rows": 1950,
"results": [
{
"agency_id": "agc_EXAMPLEPRIME00000000000000",
"name": "Example Prime Estates",
"kind": "office",
"network": "Example Network",
"type_group": "all",
"properties": 34,
"co_listed": 6,
"share": 0.019,
"portfolio_value_eur": 41500000,
"mean_eur": 1220588,
"median_eur": 940000,
"min_eur": 290000,
"max_eur": 4500000,
"p25_eur": 680000,
"p75_eur": 1330000,
"price_per_sqm_median_eur": 6100,
"price_cut": 4,
"price_raised": 1,
"price_cut_share": 0.12,
"price_cut_median_pct": -5,
"price_raised_median_pct": 3,
"overpricing_median_gap_pct": 8,
"overpricing_share_over_10_pct": 0.29,
"overpricing_cut_since_share": 0.4,
"days_on_market_min": 5,
"days_on_market_max": 410,
"days_on_market_median": 101,
"days_on_market_mean": 127,
"portfolio_value_rank": 9,
"portfolio_value_of": 650,
"new_2026-Q3": 15,
"delisted_2026-Q3": 3,
"new_2026-Q2": 14,
"delisted_2026-Q2": 4,
"new_2026-Q1": 12,
"delisted_2026-Q1": 2,
"new_2025-Q4": 11,
"delisted_2025-Q4": 3
}
]
}