{"$schema":"https://json-schema.org/draft/2020-12/schema","name":"Manhattin","description":"Rental availability and enquiry tools for properties managed in Manhattin, plus developer-console tools for debugging a property website’s integration. Every tool calls the same public API a direct integrator would, under the same keys and the same rate limits.","documentation":"https://manhattin.com/developers","openapi":"https://manhattin.com/openapi.json","transports":{"mcp":{"url":"https://manhattin.com/api/mcp","transport":"streamable-http","protocolVersion":"2025-06-18","supportedProtocolVersions":["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],"manifest":"https://manhattin.com/.well-known/mcp"},"rest":{"baseUrl":"https://manhattin.com","description":"https://manhattin.com/openapi.json"}},"authentication":{"description":"Most tools need a Manhattin API key in `Authorization: Bearer <key>` or `X-API-Key: <key>`. Three families, each scoped differently: `pk_live_` (one property), `ok_live_` (one organization), `agency_live_` (partner properties). Sending one where another is expected returns 403 INVALID_KEY. The five developer-console tools take a console token in `X-Manhattin-Console-Token` instead — a different credential, minted at /api-key/console.","keyless":["list_pricing_plans","get_openapi_specification"]},"writes":["submit_inquiry","submit_organization_inquiry","extend_console_window"],"tools":{"openai":[{"type":"function","function":{"name":"list_pricing_plans","description":"Published Manhattin subscription plans, including the free tier, with prices and features. Needs no API key — use it to check connectivity before anyone has issued you one.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"get_openapi_specification","description":"The full OpenAPI 3.1 description of the Manhattin public API: every endpoint, schema, error code and rate-limit policy. Needs no API key. Fetch this when a tool below is not enough and you need the raw contract.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"list_available_units","description":"Units on the property behind the key that can be advertised today: vacant with no lease starting later than today, plus occupied units whose lease ends within three calendar months. Rent is in the \"rent\" field. Commercial units are included — filter on \"classification\" if the caller wants residential only. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","parameters":{"type":"object","properties":{"unit_type":{"type":"string","description":"Exact match on the unit type string, e.g. \"4 1/2\". Free text."},"bedrooms":{"type":"integer","minimum":0,"description":"Exact bedroom count."},"min_rent":{"type":"number","minimum":0,"description":"Lowest market rent to include."},"max_rent":{"type":"number","minimum":0,"description":"Highest market rent to include."}},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"list_all_units","description":"Every active unit on the property, split into advertisable units and an explicit unavailable list with reasons, plus active promotions. Rent is in \"monthly_rent\" here, not \"rent\". Accepts no filters. Cached for five minutes, so a status change can take that long to appear. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"get_unit","description":"Detail for a single residential unit on the property: rent, size, features, restrictions, parking, storage and photos. Commercial units answer 404, as do unknown, inactive and other properties' units. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","parameters":{"type":"object","properties":{"unit_id":{"type":"string","description":"Unit id, as returned by list_available_units or list_all_units.","format":"uuid"}},"required":["unit_id"],"additionalProperties":false}}},{"type":"function","function":{"name":"submit_inquiry","description":"Records a prospective tenant's enquiry against the property behind the key. This WRITES: it creates a lead a property manager will act on, so only call it on someone's explicit instruction, never to test connectivity. Responds 201. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","parameters":{"type":"object","properties":{"email":{"type":"string","description":"Contact email. The only required field. Must look like name@example.com.","format":"email"},"first_name":{"type":"string","description":"Given name, stored as sent."},"last_name":{"type":"string","description":"Family name, stored as sent."},"phone":{"type":"string","description":"Phone number, stored as sent. No format validation."},"message":{"type":"string","description":"Free text. Lands in the lead notes."},"unit_id":{"type":"string","description":"Unit the enquiry is about. Must belong to the key’s scope.","format":"uuid"},"preferred_move_in":{"type":"string","description":"Desired move-in date, YYYY-MM-DD.","format":"date"},"requested_visit_date":{"type":"string","description":"Desired viewing date, YYYY-MM-DD.","format":"date"},"newsletter_signup":{"type":"boolean","description":"Whether they opted into marketing email."},"apartment_type":{"type":"string","description":"Size wanted. Normalized server-side: \"2 Bedroom\" and \"2 chambres\" both become \"4 1/2\"."},"language":{"type":"string","description":"Language of the enquiry.","enum":["EN","FR","ES"]}},"required":["email"],"additionalProperties":false}}},{"type":"function","function":{"name":"list_organization_properties","description":"Each active property in the organization with its address, amenities, photos and unit counts. \"available_units\" counts units at raw status vacant; use list_organization_available_units for the marketable figure. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"list_organization_available_units","description":"Marketable units from every active property in the organization, each carrying the property it belongs to. An unknown property_id returns an empty result, not an error. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","parameters":{"type":"object","properties":{"property_id":{"type":"string","description":"Restrict to one property.","format":"uuid"},"unit_type":{"type":"string","description":"Exact match on the unit type string."},"bedrooms":{"type":"integer","minimum":0,"description":"Exact bedroom count."},"min_rent":{"type":"number","minimum":0,"description":"Lowest market rent to include."},"max_rent":{"type":"number","minimum":0,"description":"Highest market rent to include."}},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"list_organization_units","description":"Every active unit in the organization with a computed availability status, the current lease end date, any successor lease start date and any transfer intent date. Use this when you want to apply your own display rules. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","parameters":{"type":"object","properties":{"property_id":{"type":"string","description":"Restrict to one property.","format":"uuid"}},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"submit_organization_inquiry","description":"Records an enquiry against the organization, optionally tied to a property or a unit. This WRITES a lead a person will act on — only on explicit instruction. Responds 201. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","parameters":{"type":"object","properties":{"email":{"type":"string","description":"Contact email. The only required field. Must look like name@example.com.","format":"email"},"first_name":{"type":"string","description":"Given name, stored as sent."},"last_name":{"type":"string","description":"Family name, stored as sent."},"phone":{"type":"string","description":"Phone number, stored as sent. No format validation."},"message":{"type":"string","description":"Free text. Lands in the lead notes."},"unit_id":{"type":"string","description":"Unit the enquiry is about. Must belong to the key’s scope.","format":"uuid"},"preferred_move_in":{"type":"string","description":"Desired move-in date, YYYY-MM-DD.","format":"date"},"requested_visit_date":{"type":"string","description":"Desired viewing date, YYYY-MM-DD.","format":"date"},"newsletter_signup":{"type":"boolean","description":"Whether they opted into marketing email."},"apartment_type":{"type":"string","description":"Size wanted. Normalized server-side: \"2 Bedroom\" and \"2 chambres\" both become \"4 1/2\"."},"language":{"type":"string","description":"Language of the enquiry.","enum":["EN","FR","ES"]},"property_id":{"type":"string","description":"Property the enquiry is about. Omit for a portfolio-level lead.","format":"uuid"}},"required":["email"],"additionalProperties":false}}},{"type":"function","function":{"name":"list_agency_availability","description":"Availability snapshot for the properties covered by an agency partnership: available units with full detail, unavailable ids with reasons, and a meta block with counts and a pull timestamp. Requires an agency partner API key (`agency_live_...`). Limited to five calls per day.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"describe_console_access","description":"What the developer console shows about this key: its name, the property it is bound to, the origins it may be called from, how much of its rate-limit budget is spent, when the console window closes, and how many self-extensions are left. Call this first when helping someone wire a website up — it answers \"which property am I working on and why is my call being refused\" in one request. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"list_recent_api_requests","description":"The requests this key has made recently, as received: endpoint, method, query string, origin, response status and timing. This is the difference between what an integration was meant to send and what it sent — the fastest way to find a wrong query parameter, a missing key header or a blocked origin. Captures only exist while a console window is open. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","parameters":{"type":"object","properties":{"endpoint":{"type":"string","description":"Restrict to one endpoint path, e.g. /api/public/availability."}},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"list_form_submissions","description":"Every lead this key produced, each with the request body the site posted and a verdict per field: stored, ignored, or bot-protection. The ignored list is the valuable part — a WordPress form sending \"budget_range\" gets a 201 and silently loses the field, and this is the only place that shows it. CONTACT DETAILS ARE REDACTED BY DEFAULT: these are prospective tenants' names, emails and phone numbers, not the developer's own data. Everything needed to debug a form works redacted. Pass contact_details=\"full\" only when the person has asked to see a specific record. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","parameters":{"type":"object","properties":{"contact_details":{"type":"string","description":"Leave unset to keep names, emails, phone numbers and message bodies redacted, which is right for debugging. Set to \"full\" only on an explicit request to read someone’s contact details.","enum":["redacted","full"]}},"required":[],"additionalProperties":false}}},{"type":"function","function":{"name":"test_integration","description":"Fires one request against the public API using this key, from the server, and returns the status, headers and body verbatim. Use it to prove a fix without deploying the site, and to tell \"my code is wrong\" apart from \"the key is wrong\". Read-only endpoints only. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","parameters":{"type":"object","properties":{"endpoint":{"type":"string","description":"Public API path to call, e.g. /api/public/availability."},"origin":{"type":"string","description":"Origin header to send, to test the allowlist. Optional."}},"required":["endpoint"],"additionalProperties":false}}},{"type":"function","function":{"name":"extend_console_window","description":"WRITES: extends the developer console window, which is a change to the developer's own access rather than to any tenant data. Bounded: a developer gets a fixed number of self-extensions and then has to ask Manhattin. Call it when a debugging session is about to lose its captures, not pre-emptively. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","parameters":{"type":"object","properties":{},"required":[],"additionalProperties":false}}}],"anthropic":[{"name":"list_pricing_plans","description":"Published Manhattin subscription plans, including the free tier, with prices and features. Needs no API key — use it to check connectivity before anyone has issued you one.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}},{"name":"get_openapi_specification","description":"The full OpenAPI 3.1 description of the Manhattin public API: every endpoint, schema, error code and rate-limit policy. Needs no API key. Fetch this when a tool below is not enough and you need the raw contract.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}},{"name":"list_available_units","description":"Units on the property behind the key that can be advertised today: vacant with no lease starting later than today, plus occupied units whose lease ends within three calendar months. Rent is in the \"rent\" field. Commercial units are included — filter on \"classification\" if the caller wants residential only. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","input_schema":{"type":"object","properties":{"unit_type":{"type":"string","description":"Exact match on the unit type string, e.g. \"4 1/2\". Free text."},"bedrooms":{"type":"integer","minimum":0,"description":"Exact bedroom count."},"min_rent":{"type":"number","minimum":0,"description":"Lowest market rent to include."},"max_rent":{"type":"number","minimum":0,"description":"Highest market rent to include."}},"required":[],"additionalProperties":false}},{"name":"list_all_units","description":"Every active unit on the property, split into advertisable units and an explicit unavailable list with reasons, plus active promotions. Rent is in \"monthly_rent\" here, not \"rent\". Accepts no filters. Cached for five minutes, so a status change can take that long to appear. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}},{"name":"get_unit","description":"Detail for a single residential unit on the property: rent, size, features, restrictions, parking, storage and photos. Commercial units answer 404, as do unknown, inactive and other properties' units. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","input_schema":{"type":"object","properties":{"unit_id":{"type":"string","description":"Unit id, as returned by list_available_units or list_all_units.","format":"uuid"}},"required":["unit_id"],"additionalProperties":false}},{"name":"submit_inquiry","description":"Records a prospective tenant's enquiry against the property behind the key. This WRITES: it creates a lead a property manager will act on, so only call it on someone's explicit instruction, never to test connectivity. Responds 201. Requires a property API key (`pk_live_...`) in the Authorization or X-API-Key header of the MCP request. The property is resolved from the key; there is no property argument.","input_schema":{"type":"object","properties":{"email":{"type":"string","description":"Contact email. The only required field. Must look like name@example.com.","format":"email"},"first_name":{"type":"string","description":"Given name, stored as sent."},"last_name":{"type":"string","description":"Family name, stored as sent."},"phone":{"type":"string","description":"Phone number, stored as sent. No format validation."},"message":{"type":"string","description":"Free text. Lands in the lead notes."},"unit_id":{"type":"string","description":"Unit the enquiry is about. Must belong to the key’s scope.","format":"uuid"},"preferred_move_in":{"type":"string","description":"Desired move-in date, YYYY-MM-DD.","format":"date"},"requested_visit_date":{"type":"string","description":"Desired viewing date, YYYY-MM-DD.","format":"date"},"newsletter_signup":{"type":"boolean","description":"Whether they opted into marketing email."},"apartment_type":{"type":"string","description":"Size wanted. Normalized server-side: \"2 Bedroom\" and \"2 chambres\" both become \"4 1/2\"."},"language":{"type":"string","description":"Language of the enquiry.","enum":["EN","FR","ES"]}},"required":["email"],"additionalProperties":false}},{"name":"list_organization_properties","description":"Each active property in the organization with its address, amenities, photos and unit counts. \"available_units\" counts units at raw status vacant; use list_organization_available_units for the marketable figure. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}},{"name":"list_organization_available_units","description":"Marketable units from every active property in the organization, each carrying the property it belongs to. An unknown property_id returns an empty result, not an error. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","input_schema":{"type":"object","properties":{"property_id":{"type":"string","description":"Restrict to one property.","format":"uuid"},"unit_type":{"type":"string","description":"Exact match on the unit type string."},"bedrooms":{"type":"integer","minimum":0,"description":"Exact bedroom count."},"min_rent":{"type":"number","minimum":0,"description":"Lowest market rent to include."},"max_rent":{"type":"number","minimum":0,"description":"Highest market rent to include."}},"required":[],"additionalProperties":false}},{"name":"list_organization_units","description":"Every active unit in the organization with a computed availability status, the current lease end date, any successor lease start date and any transfer intent date. Use this when you want to apply your own display rules. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","input_schema":{"type":"object","properties":{"property_id":{"type":"string","description":"Restrict to one property.","format":"uuid"}},"required":[],"additionalProperties":false}},{"name":"submit_organization_inquiry","description":"Records an enquiry against the organization, optionally tied to a property or a unit. This WRITES a lead a person will act on — only on explicit instruction. Responds 201. Requires an organization API key (`ok_live_...`). Sending a property key returns 403 INVALID_KEY.","input_schema":{"type":"object","properties":{"email":{"type":"string","description":"Contact email. The only required field. Must look like name@example.com.","format":"email"},"first_name":{"type":"string","description":"Given name, stored as sent."},"last_name":{"type":"string","description":"Family name, stored as sent."},"phone":{"type":"string","description":"Phone number, stored as sent. No format validation."},"message":{"type":"string","description":"Free text. Lands in the lead notes."},"unit_id":{"type":"string","description":"Unit the enquiry is about. Must belong to the key’s scope.","format":"uuid"},"preferred_move_in":{"type":"string","description":"Desired move-in date, YYYY-MM-DD.","format":"date"},"requested_visit_date":{"type":"string","description":"Desired viewing date, YYYY-MM-DD.","format":"date"},"newsletter_signup":{"type":"boolean","description":"Whether they opted into marketing email."},"apartment_type":{"type":"string","description":"Size wanted. Normalized server-side: \"2 Bedroom\" and \"2 chambres\" both become \"4 1/2\"."},"language":{"type":"string","description":"Language of the enquiry.","enum":["EN","FR","ES"]},"property_id":{"type":"string","description":"Property the enquiry is about. Omit for a portfolio-level lead.","format":"uuid"}},"required":["email"],"additionalProperties":false}},{"name":"list_agency_availability","description":"Availability snapshot for the properties covered by an agency partnership: available units with full detail, unavailable ids with reasons, and a meta block with counts and a pull timestamp. Requires an agency partner API key (`agency_live_...`). Limited to five calls per day.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}},{"name":"describe_console_access","description":"What the developer console shows about this key: its name, the property it is bound to, the origins it may be called from, how much of its rate-limit budget is spent, when the console window closes, and how many self-extensions are left. Call this first when helping someone wire a website up — it answers \"which property am I working on and why is my call being refused\" in one request. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}},{"name":"list_recent_api_requests","description":"The requests this key has made recently, as received: endpoint, method, query string, origin, response status and timing. This is the difference between what an integration was meant to send and what it sent — the fastest way to find a wrong query parameter, a missing key header or a blocked origin. Captures only exist while a console window is open. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","input_schema":{"type":"object","properties":{"endpoint":{"type":"string","description":"Restrict to one endpoint path, e.g. /api/public/availability."}},"required":[],"additionalProperties":false}},{"name":"list_form_submissions","description":"Every lead this key produced, each with the request body the site posted and a verdict per field: stored, ignored, or bot-protection. The ignored list is the valuable part — a WordPress form sending \"budget_range\" gets a 201 and silently loses the field, and this is the only place that shows it. CONTACT DETAILS ARE REDACTED BY DEFAULT: these are prospective tenants' names, emails and phone numbers, not the developer's own data. Everything needed to debug a form works redacted. Pass contact_details=\"full\" only when the person has asked to see a specific record. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","input_schema":{"type":"object","properties":{"contact_details":{"type":"string","description":"Leave unset to keep names, emails, phone numbers and message bodies redacted, which is right for debugging. Set to \"full\" only on an explicit request to read someone’s contact details.","enum":["redacted","full"]}},"required":[],"additionalProperties":false}},{"name":"test_integration","description":"Fires one request against the public API using this key, from the server, and returns the status, headers and body verbatim. Use it to prove a fix without deploying the site, and to tell \"my code is wrong\" apart from \"the key is wrong\". Read-only endpoints only. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","input_schema":{"type":"object","properties":{"endpoint":{"type":"string","description":"Public API path to call, e.g. /api/public/availability."},"origin":{"type":"string","description":"Origin header to send, to test the allowlist. Optional."}},"required":["endpoint"],"additionalProperties":false}},{"name":"extend_console_window","description":"WRITES: extends the developer console window, which is a change to the developer's own access rather than to any tenant data. Bounded: a developer gets a fixed number of self-extensions and then has to ask Manhattin. Call it when a debugging session is about to lose its captures, not pre-emptively. Requires a developer console token in the X-Manhattin-Console-Token header of the MCP request — NOT an API key. The developer mints one from their console at https://manhattin.com/api-key/console; it lasts at most 12 hours and never outlives the console window. Without it this answers 401.","input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false}}]}}