Deals
6 tools. Generated from the MCP server: names, inputs and prices match the code.
Dismiss Deals
Hide deals from this user's searches: deals_search, search_profiles_run and the search-profile mails leave them out from now on, and so does the Leverage app, where the same list is called "Kein Interesse". Use it for listings the user rejected, so a daily search stops showing them. Takes deal_id values from deals_search. A dismissed deal is also removed from the user's saved deals. Undo with deals_restore. Free.
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| deal_ids | array<string> | yes | Deal ids from deals_search, 1 to 50. |
RESTPOST /api/v1/deals/dismiss
Extract Deal from Document
Upload a document (base64) for deal extraction (same limits as documents_upload). Optional persist_listing (default true), extract_document_figures (default true). Returns job_id with `progress` while running; poll jobs_get. Resubmitting an identical file may return status completed immediately with deal_id and document_id. To turn the deal into a property, call properties_create({ deal_id }). Costs 2 API credits.
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| filename | string | yes | |
| content_base64 | string | yes | |
| mime | string | yes | |
| persist_listing | boolean | no | |
| extract_document_figures | boolean | no |
RESTPOST /api/v1/deals/extract/document/jobs
Restore Dismissed Deals
Undo deals_dismiss: the deals show up in searches again. Returns the ids that were dismissed and are restored now; an id that was not dismissed is skipped. A deal the dismissal took out of the saved deals stays unsaved. Free.
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| deal_ids | array<string> | yes | Deal ids from deals_search, 1 to 50. |
RESTPOST /api/v1/deals/restore
Search Deals
Geo search active deals. A new query costs 1 API credit; page on with next_cursor, free within an hour of the paid first page (a page without one pays like a new query); count_only is free. Filtering or sorting on a market value or on cashflow or return on equity (the market criteria, rental_yield_gross_market, cashflow_year_one_min, return_on_equity_year_one_min and their order_by keys, also through the profile) needs a plan that shows market values; otherwise the call answers plan_upgrade_required, unless drop_gated_criteria leaves them out. Location takes coordinates, a postcode, a city name, a structured address, free text, or `area` (one or more drawn areas as a GeoJSON MultiPolygon); no need to geocode first ('Zurich'/'Zürich', Swiss 4-digit postcodes and 'Gerechtigkeitsgasse 19, 8001 Zürich' all resolve); radius_km defaults to 10. The response echoes resolved_location (precision address|street|postcode|city|area, label, source) and warnings: check precision before calling a hit exact. criteria takes any check of the search-profile check catalog as {check_type, threshold, params}, percentages as 0-1 fractions: price, area, rooms, units, year built, condition, energy class, exclusions, amenities, market comparisons and the modelled year-one metrics (yield, cashflow, return on equity, factor, fix-and-flip margins). sale_price, living_area, land_area, number_of_rooms, number_of_units, rental_yield_gross_actual (the year-one yield floor), rental_yield_gross_market and purchase_price_factor (a ceiling) are shorthands for eight of them. property_types is a list; empty is every type. Exclusions and the energy class bound keep listings that never stated the fact, so a hit does not prove the fact is absent: when one is a hard knock-out, check the listing itself. Every requirement, range and metric floor drops a listing whose fact is unknown. Pass search_profile_id (search_profiles_list) to add every check of a saved search profile: a check set on both sides keeps the stricter bound, property_types is yours when non-empty (else the profile's), and its assumptions model the metrics. Criteria that exclude each other return no items and a criteria_conflict warning naming the fields; a metric criterion the search cannot model (a fix-and-flip margin without a fix_and_flip profile) carries a criteria_unmodelled warning. The modelled metrics (rental_yield_gross_year_one, cashflow_monthly, return_on_equity_year_one, purchase_price_factor, and with a fix-and-flip profile fixflip_profit, fixflip_margin_pct, the best-case pair and total_investment_costs_per_sqm) are year one of the property created from the listing with the profile's assumptions, else the user's defaults; they need a stated rent. rental_yield_gross_actual (IST) is non-null only where a source read the rent off the listing, rental_yield_gross_market (SOLL) comes from the market rent estimate. market_discount_pct is positive when the asking price is below the market value median. Every metric is an order_by key; desc is the highest first, rows without the metric sort last. Set include_total for a capped approximate total. count_only: true sizes a search without running it ('how many are there in X?'): it returns count, capped, resolved_location and warnings, no items. The count is capped at 1000, so capped=true means 'over 1000'; it is a close upper bound that does not subtract listings a liveness re-check drops or deals the user dismissed. Deals dismissed with deals_dismiss (or marked 'Kein Interesse' in the app) never appear in items. Criteria that read listing prose (condition, tenancy, the legal exclusions, building year, unit count, rent and costs) also start a background extraction for the listings returned, so the next search filters on more of them.
Price
- 1 API credita new query: the first page, no
cursorand nooffset - 0 API creditsa later page (
cursorfromnext_cursor, oroffset) within an hour of its paid first page - 1 API credita later page with no paid first page in the last hour
- 0 API creditswith
count_only, also viaPOST /api/v1/deals/search/count
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| location | object | yes | |
| deal_type | string | no | Values:salerent |
| property_types | array<string> | no | Values:apartmenthousemulti_family_house |
| sources | array<string> | no | Values:market_feeddirectleviimmometricamanualimported_urlimported_expose_documentimported_expose_textimmoweltkleinanzeigenis24immobiloseller_direct |
| min_platform_count | integer | no | |
| search_profile_id | integer | no | One of your search profiles (search_profiles_list): its checks are added to the criteria (the stricter bound wins), its property_types apply when you send none, and its calculation assumptions model the metrics. A search that is exactly one a Vertrieb seller provided (its place, no criterion or filter of your own) runs with the seller’s plan. |
| criteria | array<object> | no | Any criterion of the search criteria catalog; a deal must meet all of them. Combined with the shorthand fields and a search profile, the stricter bound wins. |
| sale_price | object | no | |
| living_area | object | no | |
| land_area | object | no | |
| number_of_rooms | object | no | |
| number_of_units | object | no | |
| rental_yield_gross_actual | object | no | |
| rental_yield_gross_market | object | no | |
| purchase_price_factor | object | no | |
| crawled_since | string | no | |
| loan_params | object | no | |
| calculation_strategy | string | no | The strategy the metrics are modelled with when no profile is attached; default: the account’s default strategy. A fix-and-flip criterion needs fix_and_flip.Values:buy_and_holdfix_and_flip |
| assumptions | object | no | Calculation assumptions that override the account’s defaults for the strategy when no profile is attached, as a search profile stores them (rates and shares as 0-1 fractions; null or absent: the default). loan_params overrides their financing. |
| use_default_strategy_for_cashflow | boolean | no | |
| order_by | string | no | Values:distancesale_pricesale_price_per_sqmrental_yield_gross_actualrental_yield_gross_marketrental_yield_gross_year_onepurchase_price_factorcashflow_monthlyreturn_on_equity_year_onecrawled_atstart_datemarket_discountpurchase_price_vs_marketrent_vs_markettotal_investment_costs_per_sqmfixflip_marginfixflip_profitfixflip_best_case_marginfixflip_best_case_profit |
| order_direction | string | no | Values:ascdesc |
| limit | integer | no | |
| cursor | string | no | |
| offset | integer | no | |
| include_total | boolean | no | |
| drop_gated_criteria | boolean | no | Replaying a stored search: leave out what the plan cannot filter or sort on (market values, cashflow, return on equity) instead of a refusal; a gated_criteria_dropped warning names it. |
| count_only | boolean | no | Return only how many deals the search would find (count, capped), without rows and without starting a background extraction. Paging and sort fields are ignored. |
RESTPOST /api/v1/deals/searchcount_only is its own route: POST /api/v1/deals/search/count.
Extract Deal from Text
Submit raw text/HTML for deal extraction. Returns job_id; poll jobs_get until completed; the result contains deal_id when successful. To turn the deal into a property, call properties_create({ deal_id }). Costs 1 API credit.
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| content | string | yes | |
| text_type | string | no | Values:texthtml |
| document_id | string | no | |
| persist_listing | boolean | no |
RESTPOST /api/v1/deals/extract/text/jobs
Extract Deal from URL
Extract a deal from a listing link (ImmoScout24, Immowelt, Kleinanzeigen and other public listing pages): Leverage fetches the page, so pass the URL instead of copying the listing text. Returns job_id; poll jobs_get until completed; the result contains deal_id. To turn the deal into a property, call properties_create({ deal_id }). A page that cannot be fetched or has no text fails at once with page_scrape_failed or page_content_empty and costs nothing: then send the listing text to deals_text_extract. Inside a routine only ImmoScout24, Immowelt, Immonet, Kleinanzeigen and Wohnungsbörse pages are fetched; another host fails with 403 url_not_a_listing_portal. Costs 2 API credits; a page the model judges not to be a listing fails the job and is charged.
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Public listing page, http or https. |
RESTPOST /api/v1/deals/extract/url/jobs